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.content.ActivityNotFoundException;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
21875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.content.ContentResolver;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface;
243c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.content.Intent;
25de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brownimport android.content.pm.PackageManager;
26ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamathimport android.content.pm.ResolveInfo;
27875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.database.Cursor;
28050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwoodimport android.graphics.Rect;
29875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.net.Uri;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
32875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.os.RemoteException;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
34f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
353fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringertimport android.text.TextUtils;
368d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringertimport android.util.Log;
37de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brownimport android.util.Slog;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
406d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringertimport java.util.List;
416d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides access to the system search services.
44e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani *
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>In practice, you won't interact with this class directly, as search
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * services are provided through methods in {@link android.app.Activity Activity}
478ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * and the {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}
488ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * {@link android.content.Intent Intent}.
498ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * If you do require direct access to the SearchManager, do not instantiate
508ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * this class directly. Instead, retrieve it through
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Context#getSystemService
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * context.getSystemService(Context.SEARCH_SERVICE)}.
53590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen *
543aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference">
553aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3>
563aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about using the search dialog and adding search
573aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * suggestions in your application, read the
583aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/search/index.html">Search</a> developer guide.</p>
598ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * </div>
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
61e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasanipublic class SearchManager
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements DialogInterface.OnDismissListener, DialogInterface.OnCancelListener
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
648d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
658d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    private static final boolean DBG = false;
668d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    private static final String TAG = "SearchManager";
678d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a shortcut definition for the default menu key to use for invoking search.
70e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * See Menu.Item.setAlphabeticShortcut() for more information.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static char MENU_KEY = 's';
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a shortcut definition for the default menu key to use for invoking search.
77e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * See Menu.Item.setAlphabeticShortcut() for more information.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static int MENU_KEYCODE = KeyEvent.KEYCODE_S;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
83e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Intent extra data key: Use this key with
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getStringExtra
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  content.Intent.getStringExtra()}
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain the query string from Intent.ACTION_SEARCH.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String QUERY = "query";
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
915f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * Intent extra data key: Use this key with
925f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * {@link android.content.Intent#getStringExtra
935f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     *  content.Intent.getStringExtra()}
945f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * to obtain the query string typed in by the user.
955f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * This may be different from the value of {@link #QUERY}
965f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * if the intent is the result of selecting a suggestion.
975f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * In that case, {@link #QUERY} will contain the value of
985f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * {@link #SUGGEST_COLUMN_QUERY} for the suggestion, and
995f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * {@link #USER_QUERY} will contain the string typed by the
1005f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * user.
1015f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     */
1025f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert    public final static String USER_QUERY = "user_query";
1035f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert
1045f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert    /**
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getBundleExtra
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  content.Intent.getBundleExtra()}
108e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * to obtain any additional app-specific data that was inserted by the
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * activity that launched the search.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String APP_DATA = "app_data";
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
114be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * Intent extra data key: Use {@link android.content.Intent#getBundleExtra
115be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * content.Intent.getBundleExtra(SEARCH_MODE)} to get the search mode used
116be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * to launch the intent.
117be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * The only current value for this is {@link #MODE_GLOBAL_SEARCH_SUGGESTION}.
118be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     *
119be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * @hide
120be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     */
121be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert    public final static String SEARCH_MODE = "search_mode";
122be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert
123be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert    /**
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getIntExtra content.Intent.getIntExtra()}
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain the keycode that the user used to trigger this query.  It will be zero if the
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * user simply pressed the "GO" button on the search UI.  This is primarily used in conjunction
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with the keycode attribute in the actionkey element of your searchable.xml configuration
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * file.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String ACTION_KEY = "action_key";
132e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
134875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Intent extra data key: This key will be used for the extra populated by the
135875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column.
136875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
137875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public final static String EXTRA_DATA_KEY = "intent_extra_data_key";
138a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen
139a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen    /**
14055f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * Boolean extra data key for {@link #INTENT_ACTION_GLOBAL_SEARCH} intents. If {@code true},
14155f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * the initial query should be selected when the global search activity is started, so
14255f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * that the user can easily replace it with another query.
1433c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     */
14455f3ac5f293e78618995202274f8555f2481994dBjorn Bringert    public final static String EXTRA_SELECT_QUERY = "select_query";
14532d580c360da0a0f15e7a080f4ebd0b7b514fe4cBjorn Bringert
1463c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    /**
147af5b406ad62af6f9d9e9f9f278683fb42015a4a2Leon Scroggins     * Boolean extra data key for {@link Intent#ACTION_WEB_SEARCH} intents.  If {@code true},
148af5b406ad62af6f9d9e9f9f278683fb42015a4a2Leon Scroggins     * this search should open a new browser window, rather than using an existing one.
149af5b406ad62af6f9d9e9f9f278683fb42015a4a2Leon Scroggins     */
150af5b406ad62af6f9d9e9f9f278683fb42015a4a2Leon Scroggins    public final static String EXTRA_NEW_SEARCH = "new_search";
151af5b406ad62af6f9d9e9f9f278683fb42015a4a2Leon Scroggins
152af5b406ad62af6f9d9e9f9f278683fb42015a4a2Leon Scroggins    /**
1534519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert     * Extra data key for {@link Intent#ACTION_WEB_SEARCH}. If set, the value must be a
1544519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert     * {@link PendingIntent}. The search activity handling the {@link Intent#ACTION_WEB_SEARCH}
1554519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert     * intent will fill in and launch the pending intent. The data URI will be filled in with an
1564519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert     * http or https URI, and {@link android.provider.Browser#EXTRA_HEADERS} may be filled in.
1574519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert     */
1584519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert    public static final String EXTRA_WEB_SEARCH_PENDINGINTENT = "web_search_pendingintent";
1594519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert
1604519ff6aa35b82e4d401f8af92257ffd4b176bd5Bjorn Bringert    /**
161c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * Boolean extra data key for a suggestion provider to return in {@link Cursor#getExtras} to
162c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * indicate that the search is not complete yet. This can be used by the search UI
163c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * to indicate that a search is in progress. The suggestion provider can return partial results
164c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * this way and send a change notification on the cursor when more results are available.
165c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     */
166c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani    public final static String CURSOR_EXTRA_KEY_IN_PROGRESS = "in_progress";
167c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani
168c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani    /**
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()}
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain the action message that was defined for a particular search action key and/or
172e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * suggestion.  It will be null if the search was launched by typing "enter", touched the the
173e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * "GO" button, or other means not involving any action key.
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String ACTION_MSG = "action_msg";
176e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
177e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    /**
178e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Flag to specify that the entry can be used for query refinement, i.e., the query text
179e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * in the search field can be replaced with the text in this entry, when a query refinement
180e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * icon is clicked. The suggestion list should show such a clickable icon beside the entry.
181e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * <p>Use this flag as a bit-field for {@link #SUGGEST_COLUMN_FLAGS}.
182e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     */
183e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    public final static int FLAG_QUERY_REFINEMENT = 1 << 0;
184e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Uri path for queried suggestions data.  This is the path that the search manager
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will use when querying your content provider for suggestions data based on user input
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (e.g. looking for partial matches).
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Typically you'll use this with a URI matcher.
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_URI_PATH_QUERY = "search_suggest_query";
192b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen
193b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    /**
194b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     * MIME type for suggestions data.  You'll use this in your suggestions content provider
195b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     * in the getType() function.
196b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     */
197b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen    public final static String SUGGEST_MIME_TYPE =
198b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen            "vnd.android.cursor.dir/vnd.android.search.suggest";
199b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen
200b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen    /**
201b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * Uri path for shortcut validation.  This is the path that the search manager will use when
202b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * querying your content provider to refresh a shortcutted suggestion result and to check if it
203b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * is still valid.  When asked, a source may return an up to date result, or no result.  No
204b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * result indicates the shortcut refers to a no longer valid sugggestion.
205b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     *
206b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * @see #SUGGEST_COLUMN_SHORTCUT_ID
207b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     */
208b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    public final static String SUGGEST_URI_PATH_SHORTCUT = "search_suggest_shortcut";
209e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
211b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     * MIME type for shortcut validation.  You'll use this in your suggestions content provider
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the getType() function.
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
214e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    public final static String SHORTCUT_MIME_TYPE =
215b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen            "vnd.android.cursor.item/vnd.android.search.suggest";
216d4c98c4c450a95b67fe9746675984333b7653713Karl Rosaen
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Unused - can be null or column can be omitted.</i>
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_FORMAT = "suggest_format";
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
222e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Column name for suggestions cursor.  <i>Required.</i>  This is the primary line of text that
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be presented to the user as the suggestion.
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_TEXT_1 = "suggest_text_1";
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  then all suggestions will be provided in a two-line format.  The second line of text is in
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  a much smaller appearance.
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_TEXT_2 = "suggest_text_2";
2320b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert
2330b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert    /**
2340b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * Column name for suggestions cursor.  <i>Optional.</i> This is a URL that will be shown
2350b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * as the second line of text instead of {@link #SUGGEST_COLUMN_TEXT_2}. This is a separate
2360b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * column so that the search UI knows to display the text as a URL, e.g. by using a different
2370b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * color. If this column is absent, or has the value {@code null},
2380b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * {@link #SUGGEST_COLUMN_TEXT_2} will be used instead.
2390b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     */
2400b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert    public final static String SUGGEST_COLUMN_TEXT_2_URL = "suggest_text_2_url";
2410b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
244875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  then all suggestions will be provided in a format that includes space for two small icons,
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  one at the left and one at the right of each suggestion.  The data in the column must
246875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  be a resource ID of a drawable, or a URI in one of the following formats:
247875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
248875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <ul>
249875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
250875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
251875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
252875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * </ul>
253875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
254e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
255e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * for more information on these schemes.
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_ICON_1 = "suggest_icon_1";
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
260875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  then all suggestions will be provided in a format that includes space for two small icons,
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  one at the left and one at the right of each suggestion.  The data in the column must
262875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  be a resource ID of a drawable, or a URI in one of the following formats:
263875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
264875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <ul>
265875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
266875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
267875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
268875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * </ul>
269875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
270e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
271e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * for more information on these schemes.
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_ICON_2 = "suggest_icon_2";
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this element exists at the given row, this is the action that will be used when
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * forming the suggestion's intent.  If the element is not provided, the action will be taken
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the android:searchSuggestIntentAction field in your XML metadata.  <i>At least one of
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * these must be present for the suggestion to generate an intent.</i>  Note:  If your action is
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same for all suggestions, it is more efficient to specify it using XML metadata and omit
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it from the cursor.
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_INTENT_ACTION = "suggest_intent_action";
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
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, this is the data that will be used when
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * forming the suggestion's intent.  If the element is not provided, the data will be taken
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the android:searchSuggestIntentData field in your XML metadata.  If neither source
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is provided, the Intent's data field will be null.  Note:  If your data is
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same for all suggestions, or can be described using a constant part and a specific ID,
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it is more efficient to specify it using XML metadata and omit it from the cursor.
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
295bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
296bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * this element exists at the given row, this is the data that will be used when
297bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * forming the suggestion's intent. If not provided, the Intent's extra data field will be null.
298bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * This column allows suggestions to provide additional arbitrary data which will be included as
299131234c6f134c586208ec94bfe4ae021b057cf66Mike LeBeau     * an extra under the key {@link #EXTRA_DATA_KEY}.
300bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     */
301bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath    public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
302bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath    /**
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this element exists at the given row, then "/" and this value will be appended to the data
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * field in the Intent.  This should only be used if the data field has already been set to an
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appropriate base string.
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_INTENT_DATA_ID = "suggest_intent_data_id";
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
310e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Column name for suggestions cursor.  <i>Required if action is
311e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}, optional otherwise.</i>  If this
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * column exists <i>and</i> this element exists at the given row, this is the data that will be
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * used when forming the suggestion's query.
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_QUERY = "suggest_intent_query";
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
317875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
318b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * Column name for suggestions cursor. <i>Optional.</i>  This column is used to indicate whether
319b5041368524045b6714081d14ff3c6b22598aab1Karl Rosaen     * a search suggestion should be stored as a shortcut, and whether it should be refreshed.  If
320b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * missing, the result will be stored as a shortcut and never validated.  If set to
321b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
322b5041368524045b6714081d14ff3c6b22598aab1Karl Rosaen     * Otherwise, the shortcut id will be used to check back for an up to date suggestion using
323b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * {@link #SUGGEST_URI_PATH_SHORTCUT}.
324b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     */
325b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
326b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen
327b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    /**
328ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
329ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     * that a spinner should be shown in lieu of an icon2 while the shortcut of this suggestion
330ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     * is being refreshed.
331ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     */
332ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau    public final static String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING =
333ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau            "suggest_spinner_while_refreshing";
3341c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath
3351c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath    /**
336e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
337e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * additional flags per item. Multiple flags can be specified.
338e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * <p>
339e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Must be one of {@link #FLAG_QUERY_REFINEMENT} or 0 to indicate no flags.
340e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * </p>
341e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     */
342e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    public final static String SUGGEST_COLUMN_FLAGS = "suggest_flags";
343e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
344e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    /**
345a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy     * Column name for suggestions cursor. <i>Optional.</i> This column may be
346de2ba4c8688bc32b1058433aac2f58872c8db1bfMark Brophy     * used to specify the time in {@link System#currentTimeMillis
347a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy     * System.currentTImeMillis()} (wall time in UTC) when an item was last
348a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy     * accessed within the results-providing application. If set, this may be
349a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy     * used to show more-recently-used items first.
350a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy     */
351a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy    public final static String SUGGEST_COLUMN_LAST_ACCESS_HINT = "suggest_last_access_hint";
352a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy
353a31c7aadcd0371e973000826b5998c9af8816d7fMark Brophy    /**
354b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion
355b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * should not be stored as a shortcut in global search.
356b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     */
357b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    public final static String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1";
358b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen
359b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    /**
3603fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * Query parameter added to suggestion queries to limit the number of suggestions returned.
36186917dbb9554e3e05be4ca8845a409b730120022Bjorn Bringert     * This limit is only advisory and suggestion providers may chose to ignore it.
3623fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     */
3633fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    public final static String SUGGEST_PARAMETER_LIMIT = "limit";
3643fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert
3653fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    /**
36655f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * Intent action for starting the global search activity.
36774708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert     * The global search provider should handle this intent.
36855f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     *
36955f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * Supported extra data keys: {@link #QUERY},
37055f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * {@link #EXTRA_SELECT_QUERY},
37155f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * {@link #APP_DATA}.
37274708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert     */
373e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    public final static String INTENT_ACTION_GLOBAL_SEARCH
37474708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert            = "android.search.action.GLOBAL_SEARCH";
375e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
37674708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert    /**
377875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Intent action for starting the global search settings activity.
378875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * The global search provider should handle this intent.
379875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
380e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    public final static String INTENT_ACTION_SEARCH_SETTINGS
381875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            = "android.search.action.SEARCH_SETTINGS";
382e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
3833a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau    /**
3843a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     * Intent action for starting a web search provider's settings activity.
3853a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     * Web search providers should handle this intent if they have provider-specific
3863a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     * settings to implement.
3873a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     */
3883a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau    public final static String INTENT_ACTION_WEB_SEARCH_SETTINGS
3893a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau            = "android.search.action.WEB_SEARCH_SETTINGS";
390a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen
391a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen    /**
392f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     * Intent action broadcasted to inform that the searchables list or default have changed.
393f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     * Components should handle this intent if they cache any searchable data and wish to stay
394f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     * up to date on changes.
395f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     */
396f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath    public final static String INTENT_ACTION_SEARCHABLES_CHANGED
397f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath            = "android.search.action.SEARCHABLES_CHANGED";
398e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
399d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau    /**
400ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     * Intent action to be broadcast to inform that the global search provider
4013f5cfcf2d9d60bf12127dee3be54faaf7150ff69Michael Jurka     * has changed.
402ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     */
403ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath    public final static String INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED
404ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath            = "android.search.action.GLOBAL_SEARCH_ACTIVITY_CHANGED";
405ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath
406ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath    /**
407d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau     * Intent action broadcasted to inform that the search settings have changed in some way.
408590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * Either searchables have been enabled or disabled, or a different web search provider
409590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * has been chosen.
410d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau     */
411d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau    public final static String INTENT_ACTION_SEARCH_SETTINGS_CHANGED
412d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau            = "android.search.action.SETTINGS_CHANGED";
413f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath
414f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath    /**
4154f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * This means that context is voice, and therefore the SearchDialog should
4164f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * continue showing the microphone until the user indicates that he/she does
4174f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * not want to re-speak (e.g. by typing).
4184f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     *
4194f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * @hide
4204f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     */
4214f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins    public final static String CONTEXT_IS_VOICE = "android.search.CONTEXT_IS_VOICE";
4224f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins
4234f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins    /**
4244a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III     * This means that the voice icon should not be shown at all, because the
4254a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III     * current search engine does not support voice search.
4264a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III     * @hide
4274a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III     */
4284a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III    public final static String DISABLE_VOICE_SEARCH
4294a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III            = "android.search.DISABLE_VOICE_SEARCH";
4304a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III
4314a028009468a95e932fc4fcd9ccdd358e02b1b0aLeon Scroggins III    /**
432875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Reference to the shared system search service.
433875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
4348d1538237847baf381787b881141f8c0478bef5bBjorn Bringert    private static ISearchManager mService;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Context mContext;
4378d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
438d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    /**
439d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * The package associated with this seach manager.
440d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     */
441d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    private String mAssociatedPackage;
442e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
4438d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    // package private since they are used by the inner class SearchManagerCallback
4448d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    /* package */ final Handler mHandler;
4458d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    /* package */ OnDismissListener mDismissListener = null;
4468d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    /* package */ OnCancelListener mCancelListener = null;
4478d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
448e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    private SearchDialog mSearchDialog;
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ SearchManager(Context context, Handler handler)  {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = handler;
4538d1538237847baf381787b881141f8c0478bef5bBjorn Bringert        mService = ISearchManager.Stub.asInterface(
4548d1538237847baf381787b881141f8c0478bef5bBjorn Bringert                ServiceManager.getService(Context.SEARCH_SERVICE));
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
456e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Launch search UI.
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The search manager will open a search widget in an overlapping
461e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * window, and the underlying activity may be obscured.  The search
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * entry state will remain in effect until one of the following events:
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ul>
464e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * <li>The user completes the search.  In most cases this will launch
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a search intent.</li>
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>The user uses the back, home, or other keys to exit the search.</li>
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>The application calls the {@link #stopSearch}
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method, which will hide the search window and return focus to the
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * activity from which it was launched.</li>
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Most applications will <i>not</i> use this interface to invoke search.
472e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * The primary method for invoking search is to call
473e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * {@link android.app.Activity#onSearchRequested Activity.onSearchRequested()} or
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.app.Activity#startSearch Activity.startSearch()}.
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param initialQuery A search string can be pre-entered here, but this
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is typically null or empty.
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selectInitialQuery If true, the intial query will be preselected, which means that
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * any further typing will replace it.  This is useful for cases where an entire pre-formed
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * query is being inserted.  If false, the selection point will be placed at the end of the
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inserted query.  This is useful when the inserted query is text that the user entered,
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the user would expect to be able to keep typing.  <i>This parameter is only meaningful
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if initialQuery is a non-empty string.</i>
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param launchActivity The ComponentName of the activity that has launched this search.
485e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * @param appSearchData An application can insert application-specific
486e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * context here, in order to improve quality or specificity of its own
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * searches.  This data will be returned with SEARCH intent(s).  Null if
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no extra data is required.
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param globalSearch If false, this will only launch the search that has been specifically
490e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * defined by the application (which is usually defined as a local search).  If no default
491cfa419b754332e12f8cd45244c2f3bee9d6a74bbMike LeBeau     * search is defined in the current application or activity, global search will be launched.
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If true, this will always launch a platform-global (e.g. web-based) search instead.
493e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.app.Activity#onSearchRequested
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #stopSearch
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
497e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani    public void startSearch(String initialQuery,
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            boolean selectInitialQuery,
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ComponentName launchActivity,
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Bundle appSearchData,
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            boolean globalSearch) {
502050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood        startSearch(initialQuery, selectInitialQuery, launchActivity,
503050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood                appSearchData, globalSearch, null);
504050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood    }
505050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood
506050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood    /**
507050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood     * As {@link #startSearch(String, boolean, ComponentName, Bundle, boolean)} but including
508050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood     * source bounds for the global search intent.
509050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood     *
510050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood     * @hide
511050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood     */
512050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood    public void startSearch(String initialQuery,
513050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood                            boolean selectInitialQuery,
514050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood                            ComponentName launchActivity,
515050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood                            Bundle appSearchData,
516050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood                            boolean globalSearch,
517050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood                            Rect sourceBounds) {
5183c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (globalSearch) {
519050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood            startGlobalSearch(initialQuery, selectInitialQuery, appSearchData, sourceBounds);
5203c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            return;
5213c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5223c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert
523479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani        ensureSearchDialog();
524479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani
525479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani        mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData);
526e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    }
527e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani
528e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    private void ensureSearchDialog() {
529e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mSearchDialog == null) {
530e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog = new SearchDialog(mContext, this);
531e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog.setOnCancelListener(this);
532e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog.setOnDismissListener(this);
533d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        }
534d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    }
535d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen
536d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    /**
5373c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     * Starts the global search activity.
5383c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     */
539e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    /* package */ void startGlobalSearch(String initialQuery, boolean selectInitialQuery,
540050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood            Bundle appSearchData, Rect sourceBounds) {
5413c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        ComponentName globalSearchActivity = getGlobalSearchActivity();
5423c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (globalSearchActivity == null) {
5433c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            Log.w(TAG, "No global search activity found.");
5443c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            return;
5453c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
546a94e7afb28c6bd9af6f2b0142a577086399066b2Bjorn Bringert        Intent intent = new Intent(INTENT_ACTION_GLOBAL_SEARCH);
547b8144a9c18f23c91b836736a2fcea30917153002Bjorn Bringert        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5483c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        intent.setComponent(globalSearchActivity);
5493c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        // Make sure that we have a Bundle to put source in
5503c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        if (appSearchData == null) {
5513c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert            appSearchData = new Bundle();
5523c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        } else {
5533c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert            appSearchData = new Bundle(appSearchData);
5543c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5553c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        // Set source to package name of app that starts global search, if not set already.
5563c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        if (!appSearchData.containsKey("source")) {
5573c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert            appSearchData.putString("source", mContext.getPackageName());
5583c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        }
5593c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        intent.putExtra(APP_DATA, appSearchData);
5603c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (!TextUtils.isEmpty(initialQuery)) {
56155f3ac5f293e78618995202274f8555f2481994dBjorn Bringert            intent.putExtra(QUERY, initialQuery);
5623c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5633c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (selectInitialQuery) {
56455f3ac5f293e78618995202274f8555f2481994dBjorn Bringert            intent.putExtra(EXTRA_SELECT_QUERY, selectInitialQuery);
5653c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
566050453eaf51bb3a267680dc1db2b53cb2fbfcefcMathew Inwood        intent.setSourceBounds(sourceBounds);
5673c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        try {
5683c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            if (DBG) Log.d(TAG, "Starting global search: " + intent.toUri(0));
5693c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            mContext.startActivity(intent);
5703c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        } catch (ActivityNotFoundException ex) {
5713c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            Log.e(TAG, "Global search activity not found: " + globalSearchActivity);
5723c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5733c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    }
5743c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert
5753c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    /**
576ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     * Returns a list of installed apps that handle the global search
577ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     * intent.
578ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     *
579ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     * @hide
580ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath     */
581ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath    public List<ResolveInfo> getGlobalSearchActivities() {
582ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath        try {
583ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath            return mService.getGlobalSearchActivities();
584ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath        } catch (RemoteException ex) {
585ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath            Log.e(TAG, "getGlobalSearchActivities() failed: " + ex);
586ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath            return null;
587ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath        }
588ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath    }
589ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath
590ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath    /**
5913c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     * Gets the name of the global search activity.
5923c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     */
59338015f3663dcf3765d0998f8f5398b3068dfc326Bjorn Bringert    public ComponentName getGlobalSearchActivity() {
5946cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        try {
5956cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return mService.getGlobalSearchActivity();
5966cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        } catch (RemoteException ex) {
5976cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            Log.e(TAG, "getGlobalSearchActivity() failed: " + ex);
5986cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return null;
5993c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
6003c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    }
6013c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert
6023c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    /**
603ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     * Gets the name of the web search activity.
604ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *
605ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     * @return The name of the default activity for web searches. This activity
606ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *         can be used to get web search suggestions. Returns {@code null} if
607ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *         there is no default web search activity.
608ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *
609ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     * @hide
610ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     */
611ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert    public ComponentName getWebSearchActivity() {
6126cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        try {
6136cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return mService.getWebSearchActivity();
6146cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        } catch (RemoteException ex) {
6156cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            Log.e(TAG, "getWebSearchActivity() failed: " + ex);
616ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert            return null;
617ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert        }
618ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert    }
619ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert
620ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert    /**
621d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * Similar to {@link #startSearch} but actually fires off the search query after invoking
622d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * the search dialog.  Made available for testing purposes.
623d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     *
624d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @param query The query to trigger.  If empty, request will be ignored.
625d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @param launchActivity The ComponentName of the activity that has launched this search.
626d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @param appSearchData An application can insert application-specific
627d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * context here, in order to improve quality or specificity of its own
628d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * searches.  This data will be returned with SEARCH intent(s).  Null if
629d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * no extra data is required.
630d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     *
631d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @see #startSearch
632d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     */
633d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    public void triggerSearch(String query,
634d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen                              ComponentName launchActivity,
635b782a2f4f0a3072f2677f6f10fb255c77468ae66Bjorn Bringert                              Bundle appSearchData) {
636d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        if (!mAssociatedPackage.equals(launchActivity.getPackageName())) {
637d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen            throw new IllegalArgumentException("invoking app search on a different package " +
638d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen                    "not associated with this search manager");
639d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        }
640d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        if (query == null || TextUtils.getTrimmedLength(query) == 0) {
641d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen            Log.w(TAG, "triggerSearch called with empty query, ignoring.");
642d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen            return;
643d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        }
644e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        startSearch(query, false, launchActivity, appSearchData, false);
645e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        mSearchDialog.launchQuerySearch();
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Terminate search UI.
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Typically the user will terminate the search UI by launching a
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * search or by canceling.  This function allows the underlying application
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or activity to cancel the search prematurely (for any reason).
654e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>This function can be safely called at any time (even if no search is active.)
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #startSearch
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6598d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void stopSearch() {
660e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mSearchDialog != null) {
661e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog.cancel();
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
666e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     * Determine if the Search UI is currently displayed.
667e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is provided primarily for application test purposes.
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if the search UI is currently displayed.
671e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6748d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public boolean isVisible() {
675e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        return mSearchDialog == null? false : mSearchDialog.isShowing();
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6778d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
679a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * See {@link SearchManager#setOnDismissListener} for configuring your activity to monitor
680a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * search UI state.
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
684a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * This method will be called when the search UI is dismissed. To make use of it, you must
685a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * implement this method in your activity, and call
686a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * {@link SearchManager#setOnDismissListener} to register it.
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
690e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
692a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * See {@link SearchManager#setOnCancelListener} for configuring your activity to monitor
693a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * search UI state.
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnCancelListener {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This method will be called when the search UI is canceled. To make use if it, you must
698a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * implement this method in your activity, and call
699a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * {@link SearchManager#setOnCancelListener} to register it.
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onCancel();
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set or clear the callback that will be invoked whenever the search UI is dismissed.
706e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param listener The {@link OnDismissListener} to use, or null.
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(final OnDismissListener listener) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDismissListener = listener;
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set or clear the callback that will be invoked whenever the search UI is canceled.
715e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param listener The {@link OnCancelListener} to use, or null.
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7188d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void setOnCancelListener(OnCancelListener listener) {
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCancelListener = listener;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7218d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
7220e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert    /**
7230e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     * @deprecated This method is an obsolete internal implementation detail. Do not use.
7240e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     */
7254a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn    @Deprecated
7268d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void onCancel(DialogInterface dialog) {
727e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mCancelListener != null) {
728e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mCancelListener.onCancel();
729e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        }
7308d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    }
7310e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert
7320e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert    /**
7330e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     * @deprecated This method is an obsolete internal implementation detail. Do not use.
7340e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     */
7354a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn    @Deprecated
7368d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void onDismiss(DialogInterface dialog) {
737e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mDismissListener != null) {
738e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mDismissListener.onDismiss();
739e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7430408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     * Gets information about a searchable activity.
7440408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     *
7450408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     * @param componentName The activity to get searchable information for.
7460408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     * @return Searchable information, or <code>null</code> if the activity does not
7470408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     *         exist, or is not searchable.
7480408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     */
7490408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert    public SearchableInfo getSearchableInfo(ComponentName componentName) {
7500408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert        try {
7516cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return mService.getSearchableInfo(componentName);
7528d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert        } catch (RemoteException ex) {
7538d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert            Log.e(TAG, "getSearchableInfo() failed: " + ex);
754875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            return null;
755875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
756875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
7578d1538237847baf381787b881141f8c0478bef5bBjorn Bringert
758875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
75997325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * Gets a cursor with search suggestions.
76097325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     *
76197325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @param searchable Information about how to get the suggestions.
76297325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @param query The search text entered (so far).
76397325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @return a cursor with suggestions, or <code>null</null> the suggestion query failed.
76497325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     *
76597325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @hide because SearchableInfo is not part of the API.
76697325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     */
76797325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert    public Cursor getSuggestions(SearchableInfo searchable, String query) {
7683fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        return getSuggestions(searchable, query, -1);
7693fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    }
7703fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert
7713fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    /**
7723fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * Gets a cursor with search suggestions.
7733fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     *
7743fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @param searchable Information about how to get the suggestions.
7753fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @param query The search text entered (so far).
7763fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @param limit The query limit to pass to the suggestion provider. This is advisory,
7773fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     *        the returned cursor may contain more rows. Pass {@code -1} for no limit.
7783fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @return a cursor with suggestions, or <code>null</null> the suggestion query failed.
7793fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     *
7803fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @hide because SearchableInfo is not part of the API.
7813fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     */
7823fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {
783875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (searchable == null) {
784875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            return null;
785875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
786875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
787875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        String authority = searchable.getSuggestAuthority();
788875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (authority == null) {
789875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            return null;
790875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
791875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
792875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        Uri.Builder uriBuilder = new Uri.Builder()
793875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen                .scheme(ContentResolver.SCHEME_CONTENT)
7943fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert                .authority(authority)
7953fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert                .query("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
7963fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert                .fragment("");  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
797875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
798875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // if content path provided, insert it now
799875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        final String contentPath = searchable.getSuggestPath();
800875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (contentPath != null) {
801875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            uriBuilder.appendEncodedPath(contentPath);
802875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
803875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
8043fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        // append standard suggestion query path
805875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
806875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
807875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // get the query selection, may be null
808875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        String selection = searchable.getSuggestSelection();
809875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // inject query, either as selection args or inline
810875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        String[] selArgs = null;
811875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (selection != null) {    // use selection if provided
812875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            selArgs = new String[] { query };
813875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        } else {                    // no selection, use REST pattern
814875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            uriBuilder.appendPath(query);
815875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
816875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
8173fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        if (limit > 0) {
8183fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert            uriBuilder.appendQueryParameter(SUGGEST_PARAMETER_LIMIT, String.valueOf(limit));
8193fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        }
8203fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert
8213fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        Uri uri = uriBuilder.build();
822875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
823875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // finally, make the query
8248d1538237847baf381787b881141f8c0478bef5bBjorn Bringert        return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
825875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
826e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani
8276d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert    /**
8286d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     * Returns a list of the searchable activities that can be included in global search.
829e678f46ec45076203f6260f8a26f56d838c6b6ffAmith Yamasani     *
8306d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     * @return a list containing searchable information for all searchable activities
83113107bb186d72bc80dc5609b20c71b7e77a9784dBjorn Bringert     *         that have the <code>android:includeInGlobalSearch</code> attribute set
83213107bb186d72bc80dc5609b20c71b7e77a9784dBjorn Bringert     *         in their searchable meta-data.
8336d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     */
8348d1538237847baf381787b881141f8c0478bef5bBjorn Bringert    public List<SearchableInfo> getSearchablesInGlobalSearch() {
8356d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert        try {
8368d1538237847baf381787b881141f8c0478bef5bBjorn Bringert            return mService.getSearchablesInGlobalSearch();
8376d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert        } catch (RemoteException e) {
8388d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert            Log.e(TAG, "getSearchablesInGlobalSearch() failed: " + e);
8396d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert            return null;
8406d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert        }
8416d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert    }
842f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath
843de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown    /**
84445308b1b3b1582d048845df2ee5301241e52a5cfJim Miller     * Gets an intent for launching installed assistant activity, or null if not available.
845de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown     * @return The assist intent.
846de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown     *
847de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown     * @hide
848de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown     */
849c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani    public Intent getAssistIntent(Context context) {
850f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn        return getAssistIntent(context, UserHandle.myUserId());
851c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani    }
852c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani
853c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani    /**
854c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani     * Gets an intent for launching installed assistant activity, or null if not available.
855c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani     * @return The assist intent.
856c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani     *
857c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani     * @hide
858c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani     */
859c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani    public Intent getAssistIntent(Context context, int userHandle) {
860c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani        try {
861c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            ComponentName comp = mService.getAssistIntent(userHandle);
862c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            if (comp == null) {
863c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani                return null;
864c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            }
865c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            Intent intent = new Intent(Intent.ACTION_ASSIST);
866c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            intent.setComponent(comp);
867de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown            return intent;
868c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani        } catch (RemoteException re) {
869c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            Log.e(TAG, "getAssistIntent() failed: " + re);
870c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani            return null;
871de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown        }
872de7a8ead2467a4a152a5a9b2416c8048f1b48bbbJeff Brown    }
873e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani}
874