/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app;

import static android.app.SuggestionsAdapter.getColumnString;

import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Browser;
import android.server.search.SearchableInfo;
import android.speech.RecognizerIntent;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.util.Regex;
import android.util.AndroidRuntimeException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;

import java.util.ArrayList;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * System search dialog. This is controlled by the 
 * SearchManagerService and runs in the system process.
 * 
 * @hide
 */
public class SearchDialog extends Dialog implements OnItemClickListener, OnItemSelectedListener {

    // Debugging support
    private static final boolean DBG = false;
    private static final String LOG_TAG = "SearchDialog";
    private static final boolean DBG_LOG_TIMING = false;

    private static final String INSTANCE_KEY_COMPONENT = "comp";
    private static final String INSTANCE_KEY_APPDATA = "data";
    private static final String INSTANCE_KEY_GLOBALSEARCH = "glob";
    private static final String INSTANCE_KEY_STORED_COMPONENT = "sComp";
    private static final String INSTANCE_KEY_STORED_APPDATA = "sData";
    private static final String INSTANCE_KEY_PREVIOUS_COMPONENTS = "sPrev";
    private static final String INSTANCE_KEY_USER_QUERY = "uQry";
    
    // The extra key used in an intent to the speech recognizer for in-app voice search.
    private static final String EXTRA_CALLING_PACKAGE = "calling_package";

    private static final int SEARCH_PLATE_LEFT_PADDING_GLOBAL = 12;
    private static final int SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL = 7;

    // views & widgets
    private TextView mBadgeLabel;
    private ImageView mAppIcon;
    private SearchAutoComplete mSearchAutoComplete;
    private Button mGoButton;
    private ImageButton mVoiceButton;
    private View mSearchPlate;
    private Drawable mWorkingSpinner;

    // interaction with searchable application
    private SearchableInfo mSearchable;
    private ComponentName mLaunchComponent;
    private Bundle mAppSearchData;
    private boolean mGlobalSearchMode;
    private Context mActivityContext;
    
    // Values we store to allow user to toggle between in-app search and global search.
    private ComponentName mStoredComponentName;
    private Bundle mStoredAppSearchData;
    
    // stack of previous searchables, to support the BACK key after
    // SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.
    // The top of the stack (= previous searchable) is the last element of the list,
    // since adding and removing is efficient at the end of an ArrayList.
    private ArrayList<ComponentName> mPreviousComponents;

    // For voice searching
    private Intent mVoiceWebSearchIntent;
    private Intent mVoiceAppSearchIntent;

    // support for AutoCompleteTextView suggestions display
    private SuggestionsAdapter mSuggestionsAdapter;
    
    // Whether to rewrite queries when selecting suggestions
    private static final boolean REWRITE_QUERIES = true;
    
    // The query entered by the user. This is not changed when selecting a suggestion
    // that modifies the contents of the text field. But if the user then edits
    // the suggestion, the resulting string is saved.
    private String mUserQuery;
    
    // A weak map of drawables we've gotten from other packages, so we don't load them
    // more than once.
    private final WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache =
            new WeakHashMap<String, Drawable.ConstantState>();

    // Last known IME options value for the search edit text.
    private int mSearchAutoCompleteImeOptions;

    /**
     * Constructor - fires it up and makes it look like the search UI.
     * 
     * @param context Application Context we can use for system acess
     */
    public SearchDialog(Context context) {
        super(context, com.android.internal.R.style.Theme_GlobalSearchBar);
    }

    /**
     * We create the search dialog just once, and it stays around (hidden)
     * until activated by the user.
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(com.android.internal.R.layout.search_bar);

        Window theWindow = getWindow();
        WindowManager.LayoutParams lp = theWindow.getAttributes();
        lp.type = WindowManager.LayoutParams.TYPE_SEARCH_BAR;
        lp.width = ViewGroup.LayoutParams.FILL_PARENT;
        // taking up the whole window (even when transparent) is less than ideal,
        // but necessary to show the popup window until the window manager supports
        // having windows anchored by their parent but not clipped by them.
        lp.height = ViewGroup.LayoutParams.FILL_PARENT;
        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
        theWindow.setAttributes(lp);

        // get the view elements for local access
        mBadgeLabel = (TextView) findViewById(com.android.internal.R.id.search_badge);
        mSearchAutoComplete = (SearchAutoComplete)
                findViewById(com.android.internal.R.id.search_src_text);
        mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon);
        mGoButton = (Button) findViewById(com.android.internal.R.id.search_go_btn);
        mVoiceButton = (ImageButton) findViewById(com.android.internal.R.id.search_voice_btn);
        mSearchPlate = findViewById(com.android.internal.R.id.search_plate);
        mWorkingSpinner = getContext().getResources().
                getDrawable(com.android.internal.R.drawable.search_spinner);
        
        // attach listeners
        mSearchAutoComplete.addTextChangedListener(mTextWatcher);
        mSearchAutoComplete.setOnKeyListener(mTextKeyListener);
        mSearchAutoComplete.setOnItemClickListener(this);
        mSearchAutoComplete.setOnItemSelectedListener(this);
        mGoButton.setOnClickListener(mGoButtonClickListener);
        mGoButton.setOnKeyListener(mButtonsKeyListener);
        mVoiceButton.setOnClickListener(mVoiceButtonClickListener);
        mVoiceButton.setOnKeyListener(mButtonsKeyListener);

        mSearchAutoComplete.setSearchDialog(this);
        
        // pre-hide all the extraneous elements
        mBadgeLabel.setVisibility(View.GONE);

        // Additional adjustments to make Dialog work for Search

        // Touching outside of the search dialog will dismiss it 
        setCanceledOnTouchOutside(true);

        // Save voice intent for later queries/launching
        mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
        mVoiceWebSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mVoiceWebSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        
        mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        mSearchAutoCompleteImeOptions = mSearchAutoComplete.getImeOptions();
    }

    /**
     * Set up the search dialog
     * 
     * @return true if search dialog launched, false if not
     */
    public boolean show(String initialQuery, boolean selectInitialQuery,
            ComponentName componentName, Bundle appSearchData, boolean globalSearch) {

        // Reset any stored values from last time dialog was shown.
        mStoredComponentName = null;
        mStoredAppSearchData = null;

        boolean success = doShow(initialQuery, selectInitialQuery, componentName, appSearchData,
                globalSearch);
        if (success) {
            // Display the drop down as soon as possible instead of waiting for the rest of the
            // pending UI stuff to get done, so that things appear faster to the user.
            mSearchAutoComplete.showDropDownAfterLayout();
        }
        return success;
    }
    
    /**
     * Called in response to a press of the hard search button in
     * {@link #onKeyDown(int, KeyEvent)}, this method toggles between in-app
     * search and global search when relevant.
     * 
     * If pressed within an in-app search context, this switches the search dialog out to
     * global search. If pressed within a global search context that was originally an in-app
     * search context, this switches back to the in-app search context. If pressed within a
     * global search context that has no original in-app search context (e.g., global search
     * from Home), this does nothing.
     * 
     * @return false if we wanted to toggle context but could not do so successfully, true
     * in all other cases
     */
    private boolean toggleGlobalSearch() {
        String currentSearchText = mSearchAutoComplete.getText().toString();
        if (!mGlobalSearchMode) {
            mStoredComponentName = mLaunchComponent;
            mStoredAppSearchData = mAppSearchData;
            return doShow(currentSearchText, false, null, mAppSearchData, true);
        } else {
            if (mStoredComponentName != null) {
                // This means we should toggle *back* to an in-app search context from
                // global search.
                return doShow(currentSearchText, false, mStoredComponentName,
                        mStoredAppSearchData, false);
            } else {
                return true;
            }
        }
    }
    
    /**
     * Does the rest of the work required to show the search dialog. Called by both
     * {@link #show(String, boolean, ComponentName, Bundle, boolean)} and
     * {@link #toggleGlobalSearch()}.
     * 
     * @return true if search dialog showed, false if not
     */
    private boolean doShow(String initialQuery, boolean selectInitialQuery,
            ComponentName componentName, Bundle appSearchData,
            boolean globalSearch) {
        // set up the searchable and show the dialog
        if (!show(componentName, appSearchData, globalSearch)) {
            return false;
        }

        // finally, load the user's initial text (which may trigger suggestions)
        setUserQuery(initialQuery);
        if (selectInitialQuery) {
            mSearchAutoComplete.selectAll();
        }

        return true;
    }

    /**
     * Sets up the search dialog and shows it.
     * 
     * @return <code>true</code> if search dialog launched
     */
    private boolean show(ComponentName componentName, Bundle appSearchData, 
            boolean globalSearch) {
        
        if (DBG) { 
            Log.d(LOG_TAG, "show(" + componentName + ", " 
                    + appSearchData + ", " + globalSearch + ")");
        }
        
        SearchManager searchManager = (SearchManager)
                mContext.getSystemService(Context.SEARCH_SERVICE);
        // Try to get the searchable info for the provided component (or for global search,
        // if globalSearch == true).
        mSearchable = searchManager.getSearchableInfo(componentName, globalSearch);
        
        // If we got back nothing, and it wasn't a request for global search, then try again
        // for global search, as we'll try to launch that in lieu of any component-specific search.
        if (!globalSearch && mSearchable == null) {
            globalSearch = true;
            mSearchable = searchManager.getSearchableInfo(componentName, globalSearch);
        }

        // If there's not even a searchable info available for global search, then really give up.
        if (mSearchable == null) {
            Log.w(LOG_TAG, "No global search provider.");
            return false;
        }

        mLaunchComponent = componentName;
        mAppSearchData = appSearchData;
        // Using globalSearch here is just an optimization, just calling
        // isDefaultSearchable() should always give the same result.
        mGlobalSearchMode = globalSearch || searchManager.isDefaultSearchable(mSearchable);
        mActivityContext = mSearchable.getActivityContext(getContext());
        
        // show the dialog. this will call onStart().
        if (!isShowing()) {            
            // The Dialog uses a ContextThemeWrapper for the context; use this to change the
            // theme out from underneath us, between the global search theme and the in-app
            // search theme. They are identical except that the global search theme does not
            // dim the background of the window (because global search is full screen so it's
            // not needed and this should save a little bit of time on global search invocation).
            Object context = getContext();
            if (context instanceof ContextThemeWrapper) {
                ContextThemeWrapper wrapper = (ContextThemeWrapper) context;
                if (globalSearch) {
                    wrapper.setTheme(com.android.internal.R.style.Theme_GlobalSearchBar);
                } else {
                    wrapper.setTheme(com.android.internal.R.style.Theme_SearchBar);
                }
            }
            show();
        }
        updateUI();
        
        return true;
    }

    /**
     * The search dialog is being dismissed, so handle all of the local shutdown operations.
     * 
     * This function is designed to be idempotent so that dismiss() can be safely called at any time
     * (even if already closed) and more likely to really dump any memory.  No leaks!
     */
    @Override
    public void onStop() {
        super.onStop();

        closeSuggestionsAdapter();
        
        // dump extra memory we're hanging on to
        mLaunchComponent = null;
        mAppSearchData = null;
        mSearchable = null;
        mActivityContext = null;
        mUserQuery = null;
        mPreviousComponents = null;
    }

    /**
     * Sets the search dialog to the 'working' state, which shows a working spinner in the
     * right hand size of the text field.
     * 
     * @param working true to show spinner, false to hide spinner
     */
    public void setWorking(boolean working) {
        if (working) {
            mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
                    null, null, mWorkingSpinner, null);
            ((Animatable) mWorkingSpinner).start();
        } else {
            mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
                    null, null, null, null);
            ((Animatable) mWorkingSpinner).stop();
        }
    }
    
    /**
     * Closes and gets rid of the suggestions adapter.
     */
    private void closeSuggestionsAdapter() {
        // remove the adapter from the autocomplete first, to avoid any updates
        // when we drop the cursor
        mSearchAutoComplete.setAdapter((SuggestionsAdapter)null);
        // close any leftover cursor
        if (mSuggestionsAdapter != null) {
            mSuggestionsAdapter.changeCursor(null);
        }
        mSuggestionsAdapter = null;
    }
    
    /**
     * Save the minimal set of data necessary to recreate the search
     * 
     * @return A bundle with the state of the dialog, or {@code null} if the search
     *         dialog is not showing.
     */
    @Override
    public Bundle onSaveInstanceState() {
        if (!isShowing()) return null;

        Bundle bundle = new Bundle();

        // setup info so I can recreate this particular search       
        bundle.putParcelable(INSTANCE_KEY_COMPONENT, mLaunchComponent);
        bundle.putBundle(INSTANCE_KEY_APPDATA, mAppSearchData);
        bundle.putBoolean(INSTANCE_KEY_GLOBALSEARCH, mGlobalSearchMode);
        bundle.putParcelable(INSTANCE_KEY_STORED_COMPONENT, mStoredComponentName);
        bundle.putBundle(INSTANCE_KEY_STORED_APPDATA, mStoredAppSearchData);
        bundle.putParcelableArrayList(INSTANCE_KEY_PREVIOUS_COMPONENTS, mPreviousComponents);
        bundle.putString(INSTANCE_KEY_USER_QUERY, mUserQuery);

        return bundle;
    }

    /**
     * Restore the state of the dialog from a previously saved bundle.
     * 
     * TODO: go through this and make sure that it saves everything that is saved
     *
     * @param savedInstanceState The state of the dialog previously saved by
     *     {@link #onSaveInstanceState()}.
     */
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState == null) return;

        ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT);
        Bundle appSearchData = savedInstanceState.getBundle(INSTANCE_KEY_APPDATA);
        boolean globalSearch = savedInstanceState.getBoolean(INSTANCE_KEY_GLOBALSEARCH);
        ComponentName storedComponentName =
                savedInstanceState.getParcelable(INSTANCE_KEY_STORED_COMPONENT);
        Bundle storedAppSearchData =
                savedInstanceState.getBundle(INSTANCE_KEY_STORED_APPDATA);
        ArrayList<ComponentName> previousComponents =
                savedInstanceState.getParcelableArrayList(INSTANCE_KEY_PREVIOUS_COMPONENTS);
        String userQuery = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY);

        // Set stored state
        mStoredComponentName = storedComponentName;
        mStoredAppSearchData = storedAppSearchData;
        mPreviousComponents = previousComponents;

        // show the dialog.
        if (!doShow(userQuery, false, launchComponent, appSearchData, globalSearch)) {
            // for some reason, we couldn't re-instantiate
            return;
        }
    }
    
    /**
     * Called after resources have changed, e.g. after screen rotation or locale change.
     */
    public void onConfigurationChanged() {
        if (isShowing()) {
            // Redraw (resources may have changed)
            updateSearchButton();
            updateSearchAppIcon();
            updateSearchBadge();
            updateQueryHint();
        } 
    }
    
    /**
     * Update the UI according to the info in the current value of {@link #mSearchable}.
     */
    private void updateUI() {
        if (mSearchable != null) {
            mDecor.setVisibility(View.VISIBLE);
            updateSearchAutoComplete();
            updateSearchButton();
            updateSearchAppIcon();
            updateSearchBadge();
            updateQueryHint();
            updateVoiceButton();
            
            // In order to properly configure the input method (if one is being used), we
            // need to let it know if we'll be providing suggestions.  Although it would be
            // difficult/expensive to know if every last detail has been configured properly, we 
            // can at least see if a suggestions provider has been configured, and use that
            // as our trigger.
            int inputType = mSearchable.getInputType();
            // We only touch this if the input type is set up for text (which it almost certainly
            // should be, in the case of search!)
            if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) {
                // The existence of a suggestions authority is the proxy for "suggestions 
                // are available here"
                inputType &= ~InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE;
                if (mSearchable.getSuggestAuthority() != null) {
                    inputType |= InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE;
                }
            }
            mSearchAutoComplete.setInputType(inputType);
            mSearchAutoCompleteImeOptions = mSearchable.getImeOptions();
            mSearchAutoComplete.setImeOptions(mSearchAutoCompleteImeOptions);
        }
    }
    
    /**
     * Updates the auto-complete text view.
     */
    private void updateSearchAutoComplete() {
        // close any existing suggestions adapter
        closeSuggestionsAdapter();
        
        mSearchAutoComplete.setDropDownAnimationStyle(0); // no animation
        mSearchAutoComplete.setThreshold(mSearchable.getSuggestThreshold());
        // we dismiss the entire dialog instead
        mSearchAutoComplete.setDropDownDismissedOnCompletion(false);

        if (mGlobalSearchMode) {
            mSearchAutoComplete.setDropDownAlwaysVisible(true);  // fill space until results come in
        } else {
            mSearchAutoComplete.setDropDownAlwaysVisible(false);
        }

        // attach the suggestions adapter, if suggestions are available
        // The existence of a suggestions authority is the proxy for "suggestions available here"
        if (mSearchable.getSuggestAuthority() != null) {
            mSuggestionsAdapter = new SuggestionsAdapter(getContext(), this, mSearchable, 
                    mOutsideDrawablesCache, mGlobalSearchMode);
            mSearchAutoComplete.setAdapter(mSuggestionsAdapter);
        }
    }

    /**    
     * Update the text in the search button.  Note: This is deprecated functionality, for 
     * 1.0 compatibility only.
     */  
    private void updateSearchButton() { 
        String textLabel = null;
        Drawable iconLabel = null;
        int textId = mSearchable.getSearchButtonText(); 
        if (textId != 0) {
            textLabel = mActivityContext.getResources().getString(textId);  
        } else {
            iconLabel = getContext().getResources().
                    getDrawable(com.android.internal.R.drawable.ic_btn_search);
        }
        mGoButton.setText(textLabel);
        mGoButton.setCompoundDrawablesWithIntrinsicBounds(iconLabel, null, null, null);
    }
    
    private void updateSearchAppIcon() {
        if (mGlobalSearchMode) {
            mAppIcon.setImageResource(0);
            mAppIcon.setVisibility(View.GONE);
            mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL,
                    mSearchPlate.getPaddingTop(),
                    mSearchPlate.getPaddingRight(),
                    mSearchPlate.getPaddingBottom());
        } else {
            PackageManager pm = getContext().getPackageManager();
            Drawable icon;
            try {
                ActivityInfo info = pm.getActivityInfo(mLaunchComponent, 0);
                icon = pm.getApplicationIcon(info.applicationInfo);
                if (DBG) Log.d(LOG_TAG, "Using app-specific icon");
            } catch (NameNotFoundException e) {
                icon = pm.getDefaultActivityIcon();
                Log.w(LOG_TAG, mLaunchComponent + " not found, using generic app icon");
            }
            mAppIcon.setImageDrawable(icon);
            mAppIcon.setVisibility(View.VISIBLE);
            mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL,
                    mSearchPlate.getPaddingTop(),
                    mSearchPlate.getPaddingRight(),
                    mSearchPlate.getPaddingBottom());
        }
    }

    /**
     * Setup the search "Badge" if requested by mode flags.
     */
    private void updateSearchBadge() {
        // assume both hidden
        int visibility = View.GONE;
        Drawable icon = null;
        CharSequence text = null;
        
        // optionally show one or the other.
        if (mSearchable.useBadgeIcon()) {
            icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
            visibility = View.VISIBLE;
            if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
        } else if (mSearchable.useBadgeLabel()) {
            text = mActivityContext.getResources().getText(mSearchable.getLabelId()).toString();
            visibility = View.VISIBLE;
            if (DBG) Log.d(LOG_TAG, "Using badge label: " + mSearchable.getLabelId());
        }
        
        mBadgeLabel.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
        mBadgeLabel.setText(text);
        mBadgeLabel.setVisibility(visibility);
    }

    /**
     * Update the hint in the query text field.
     */
    private void updateQueryHint() {
        if (isShowing()) {
            String hint = null;
            if (mSearchable != null) {
                int hintId = mSearchable.getHintId();
                if (hintId != 0) {
                    hint = mActivityContext.getString(hintId);
                }
            }
            mSearchAutoComplete.setHint(hint);
        }
    }

    /**
     * Update the visibility of the voice button.  There are actually two voice search modes, 
     * either of which will activate the button.
     */
    private void updateVoiceButton() {
        int visibility = View.GONE;
        if (mSearchable.getVoiceSearchEnabled()) {
            Intent testIntent = null;
            if (mSearchable.getVoiceSearchLaunchWebSearch()) {
                testIntent = mVoiceWebSearchIntent;
            } else if (mSearchable.getVoiceSearchLaunchRecognizer()) {
                testIntent = mVoiceAppSearchIntent;
            }      
            if (testIntent != null) {
                ResolveInfo ri = getContext().getPackageManager().
                        resolveActivity(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
                if (ri != null) {
                    visibility = View.VISIBLE;
                }
            }
        }
        mVoiceButton.setVisibility(visibility);
    }
    
    /**
     * Listeners of various types
     */

    /**
     * {@link Dialog#onTouchEvent(MotionEvent)} will cancel the dialog only when the
     * touch is outside the window. But the window includes space for the drop-down,
     * so we also cancel on taps outside the search bar when the drop-down is not showing.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // cancel if the drop-down is not showing and the touch event was outside the search plate
        if (!mSearchAutoComplete.isPopupShowing() && isOutOfBounds(mSearchPlate, event)) {
            if (DBG) Log.d(LOG_TAG, "Pop-up not showing and outside of search plate.");
            cancel();
            return true;
        }
        // Let Dialog handle events outside the window while the pop-up is showing.
        return super.onTouchEvent(event);
    }
    
    private boolean isOutOfBounds(View v, MotionEvent event) {
        final int x = (int) event.getX();
        final int y = (int) event.getY();
        final int slop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop();
        return (x < -slop) || (y < -slop)
                || (x > (v.getWidth()+slop))
                || (y > (v.getHeight()+slop));
    }
    
    /**
     * Dialog's OnKeyListener implements various search-specific functionality
     *
     * @param keyCode This is the keycode of the typed key, and is the same value as
     *        found in the KeyEvent parameter.
     * @param event The complete event record for the typed key
     *
     * @return Return true if the event was handled here, or false if not.
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (DBG) Log.d(LOG_TAG, "onKeyDown(" + keyCode + "," + event + ")");
        if (mSearchable == null) {
            return false;
        }

        // handle back key to go back to previous searchable, etc.
        if (handleBackKey(keyCode, event)) {
            return true;
        }
        
        if (keyCode == KeyEvent.KEYCODE_SEARCH) {
            // If the search key is pressed, toggle between global and in-app search. If we are
            // currently doing global search and there is no in-app search context to toggle to,
            // just don't do anything.
            return toggleGlobalSearch();
        }

        // if it's an action specified by the searchable activity, launch the
        // entered query with the action key
        SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
        if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) {
            launchQuerySearch(keyCode, actionKey.getQueryActionMsg());
            return true;
        }
        
        return false;
    }
    
    /**
     * Callback to watch the textedit field for empty/non-empty
     */
    private TextWatcher mTextWatcher = new TextWatcher() {

        public void beforeTextChanged(CharSequence s, int start, int before, int after) { }

        public void onTextChanged(CharSequence s, int start,
                int before, int after) {
            if (DBG_LOG_TIMING) {
                dbgLogTiming("onTextChanged()");
            }
            if (mSearchable == null) {
                return;
            }
            updateWidgetState();
            if (!mSearchAutoComplete.isPerformingCompletion()) {
                // The user changed the query, remember it.
                mUserQuery = s == null ? "" : s.toString();
            }
        }

        public void afterTextChanged(Editable s) {
            if (mSearchable == null) {
                return;
            }
            if (mSearchable.autoUrlDetect() && !mSearchAutoComplete.isPerformingCompletion()) {
                // The user changed the query, check if it is a URL and if so change the search
                // button in the soft keyboard to the 'Go' button.
                int options = (mSearchAutoComplete.getImeOptions() & (~EditorInfo.IME_MASK_ACTION));
                if (Regex.WEB_URL_PATTERN.matcher(mUserQuery).matches()) {
                    options = options | EditorInfo.IME_ACTION_GO;
                } else {
                    options = options | EditorInfo.IME_ACTION_SEARCH;
                }
                if (options != mSearchAutoCompleteImeOptions) {
                    mSearchAutoCompleteImeOptions = options;
                    mSearchAutoComplete.setImeOptions(options);
                    // This call is required to update the soft keyboard UI with latest IME flags.
                    mSearchAutoComplete.setInputType(mSearchAutoComplete.getInputType());
                }
            }
        }
    };

    /**
     * Enable/Disable the cancel button based on edit text state (any text?)
     */
    private void updateWidgetState() {
        // enable the button if we have one or more non-space characters
        boolean enabled = !mSearchAutoComplete.isEmpty();
        mGoButton.setEnabled(enabled);
        mGoButton.setFocusable(enabled);
    }

    /**
     * React to typing in the GO search button by refocusing to EditText. 
     * Continue typing the query.
     */
    View.OnKeyListener mButtonsKeyListener = new View.OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // guard against possible race conditions
            if (mSearchable == null) {
                return false;
            }
            
            if (!event.isSystem() && 
                    (keyCode != KeyEvent.KEYCODE_DPAD_UP) &&
                    (keyCode != KeyEvent.KEYCODE_DPAD_DOWN) &&
                    (keyCode != KeyEvent.KEYCODE_DPAD_LEFT) &&
                    (keyCode != KeyEvent.KEYCODE_DPAD_RIGHT) &&
                    (keyCode != KeyEvent.KEYCODE_DPAD_CENTER)) {
                // restore focus and give key to EditText ...
                if (mSearchAutoComplete.requestFocus()) {
                    return mSearchAutoComplete.dispatchKeyEvent(event);
                }
            }

            return false;
        }
    };

    /**
     * React to a click in the GO button by launching a search.
     */
    View.OnClickListener mGoButtonClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            // guard against possible race conditions
            if (mSearchable == null) {
                return;
            }
            launchQuerySearch();
        }
    };
    
    /**
     * React to a click in the voice search button.
     */
    View.OnClickListener mVoiceButtonClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            // guard against possible race conditions
            if (mSearchable == null) {
                return;
            }
            try {
                if (mSearchable.getVoiceSearchLaunchWebSearch()) {
                    getContext().startActivity(mVoiceWebSearchIntent);
                } else if (mSearchable.getVoiceSearchLaunchRecognizer()) {
                    Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);
                    getContext().startActivity(appSearchIntent);
                }
            } catch (ActivityNotFoundException e) {
                // Should not happen, since we check the availability of
                // voice search before showing the button. But just in case...
                Log.w(LOG_TAG, "Could not find voice search activity");
            }
         }
    };
    
    /**
     * Create and return an Intent that can launch the voice search activity, perform a specific
     * voice transcription, and forward the results to the searchable activity.
     * 
     * @param baseIntent The voice app search intent to start from
     * @return A completely-configured intent ready to send to the voice search activity
     */
    private Intent createVoiceAppSearchIntent(Intent baseIntent) {
        ComponentName searchActivity = mSearchable.getSearchActivity();
        
        // create the necessary intent to set up a search-and-forward operation
        // in the voice search system.   We have to keep the bundle separate,
        // because it becomes immutable once it enters the PendingIntent
        Intent queryIntent = new Intent(Intent.ACTION_SEARCH);
        queryIntent.setComponent(searchActivity);
        PendingIntent pending = PendingIntent.getActivity(
                getContext(), 0, queryIntent, PendingIntent.FLAG_ONE_SHOT);
        
        // Now set up the bundle that will be inserted into the pending intent
        // when it's time to do the search.  We always build it here (even if empty)
        // because the voice search activity will always need to insert "QUERY" into
        // it anyway.
        Bundle queryExtras = new Bundle();
        if (mAppSearchData != null) {
            queryExtras.putBundle(SearchManager.APP_DATA, mAppSearchData);
        }
        
        // Now build the intent to launch the voice search.  Add all necessary
        // extras to launch the voice recognizer, and then all the necessary extras
        // to forward the results to the searchable activity
        Intent voiceIntent = new Intent(baseIntent);
        
        // Add all of the configuration options supplied by the searchable's metadata
        String languageModel = RecognizerIntent.LANGUAGE_MODEL_FREE_FORM;
        String prompt = null;
        String language = null;
        int maxResults = 1;
        Resources resources = mActivityContext.getResources();
        if (mSearchable.getVoiceLanguageModeId() != 0) {
            languageModel = resources.getString(mSearchable.getVoiceLanguageModeId());
        }
        if (mSearchable.getVoicePromptTextId() != 0) {
            prompt = resources.getString(mSearchable.getVoicePromptTextId());
        }
        if (mSearchable.getVoiceLanguageId() != 0) {
            language = resources.getString(mSearchable.getVoiceLanguageId());
        }
        if (mSearchable.getVoiceMaxResults() != 0) {
            maxResults = mSearchable.getVoiceMaxResults();
        }
        voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, languageModel);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
        voiceIntent.putExtra(EXTRA_CALLING_PACKAGE,
                searchActivity == null ? null : searchActivity.toShortString());
        
        // Add the values that configure forwarding the results
        voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, queryExtras);
        
        return voiceIntent;
    }

    /**
     * Corrects http/https typo errors in the given url string, and if the protocol specifier was
     * not present defaults to http.
     * 
     * @param inUrl URL to check and fix
     * @return fixed URL string.
     */
    private String fixUrl(String inUrl) {
        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
            return inUrl;

        if (inUrl.startsWith("http:") || inUrl.startsWith("https:")) {
            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
                inUrl = inUrl.replaceFirst("/", "//");
            } else {
                inUrl = inUrl.replaceFirst(":", "://");
            }
        }

        if (inUrl.indexOf("://") == -1) {
            inUrl = "http://" + inUrl;
        }

        return inUrl;
    }

    /**
     * React to the user typing "enter" or other hardwired keys while typing in the search box.
     * This handles these special keys while the edit box has focus.
     */
    View.OnKeyListener mTextKeyListener = new View.OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // guard against possible race conditions
            if (mSearchable == null) {
                return false;
            }

            if (DBG_LOG_TIMING) dbgLogTiming("doTextKey()");
            if (DBG) { 
                Log.d(LOG_TAG, "mTextListener.onKey(" + keyCode + "," + event 
                        + "), selection: " + mSearchAutoComplete.getListSelection());
            }
            
            // If a suggestion is selected, handle enter, search key, and action keys 
            // as presses on the selected suggestion
            if (mSearchAutoComplete.isPopupShowing() && 
                    mSearchAutoComplete.getListSelection() != ListView.INVALID_POSITION) {
                return onSuggestionsKey(v, keyCode, event);
            }

            // If there is text in the query box, handle enter, and action keys
            // The search key is handled by the dialog's onKeyDown(). 
            if (!mSearchAutoComplete.isEmpty()) {
                if (keyCode == KeyEvent.KEYCODE_ENTER 
                        && event.getAction() == KeyEvent.ACTION_UP) {
                    v.cancelLongPress();

                    // If this is a url entered by the user & we displayed the 'Go' button which
                    // the user clicked, launch the url instead of using it as a search query.
                    if (mSearchable.autoUrlDetect() &&
                        (mSearchAutoCompleteImeOptions & EditorInfo.IME_MASK_ACTION)
                                == EditorInfo.IME_ACTION_GO) {
                        Uri uri = Uri.parse(fixUrl(mSearchAutoComplete.getText().toString()));
                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        launchIntent(intent);
                    } else {
                        // Launch as a regular search.
                        launchQuerySearch();
                    }
                    return true;
                }
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
                    if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) {
                        launchQuerySearch(keyCode, actionKey.getQueryActionMsg());
                        return true;
                    }
                }
            }
            return false;
        }
    };

    @Override
    public void hide() {
        if (!isShowing()) return;

        // We made sure the IME was displayed, so also make sure it is closed
        // when we go away.
        InputMethodManager imm = (InputMethodManager)getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(
                    getWindow().getDecorView().getWindowToken(), 0);
        }

        super.hide();
    }

    /**
     * React to the user typing while in the suggestions list. First, check for action
     * keys. If not handled, try refocusing regular characters into the EditText. 
     */
    private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) {
        // guard against possible race conditions (late arrival after dismiss)
        if (mSearchable == null) {
            return false;
        }
        if (mSuggestionsAdapter == null) {
            return false;
        }
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (DBG_LOG_TIMING) {
                dbgLogTiming("onSuggestionsKey()");
            }
            
            // First, check for enter or search (both of which we'll treat as a "click")
            if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH) {
                int position = mSearchAutoComplete.getListSelection();
                return launchSuggestion(position);
            }
            
            // Next, check for left/right moves, which we use to "return" the user to the edit view
            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
                // give "focus" to text editor, with cursor at the beginning if
                // left key, at end if right key
                // TODO: Reverse left/right for right-to-left languages, e.g. Arabic
                int selPoint = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 
                        0 : mSearchAutoComplete.length();
                mSearchAutoComplete.setSelection(selPoint);
                mSearchAutoComplete.setListSelection(0);
                mSearchAutoComplete.clearListSelection();
                mSearchAutoComplete.ensureImeVisible();
                
                return true;
            }
            
            // Next, check for an "up and out" move
            if (keyCode == KeyEvent.KEYCODE_DPAD_UP 
                    && 0 == mSearchAutoComplete.getListSelection()) {
                restoreUserQuery();
                // let ACTV complete the move
                return false;
            }
            
            // Next, check for an "action key"
            SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
            if ((actionKey != null) && 
                    ((actionKey.getSuggestActionMsg() != null) || 
                     (actionKey.getSuggestActionMsgColumn() != null))) {
                // launch suggestion using action key column
                int position = mSearchAutoComplete.getListSelection();
                if (position != ListView.INVALID_POSITION) {
                    Cursor c = mSuggestionsAdapter.getCursor();
                    if (c.moveToPosition(position)) {
                        final String actionMsg = getActionKeyMessage(c, actionKey);
                        if (actionMsg != null && (actionMsg.length() > 0)) {
                            return launchSuggestion(position, keyCode, actionMsg);
                        }
                    }
                }
            }
        }
        return false;
    }
    
    /**
     * Launch a search for the text in the query text field.
     */
    protected void launchQuerySearch()  {
        launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null);
    }

    /**
     * Launch a search for the text in the query text field.
     *
     * @param actionKey The key code of the action key that was pressed,
     *        or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
     * @param actionMsg The message for the action key that was pressed,
     *        or <code>null</code> if none.
     */
    protected void launchQuerySearch(int actionKey, String actionMsg)  {
        String query = mSearchAutoComplete.getText().toString();
        String action = mGlobalSearchMode ? Intent.ACTION_WEB_SEARCH : Intent.ACTION_SEARCH;
        Intent intent = createIntent(action, null, null, query, null,
                actionKey, actionMsg);
        launchIntent(intent);
    }
    
    /**
     * Launches an intent based on a suggestion.
     * 
     * @param position The index of the suggestion to create the intent from.
     * @return true if a successful launch, false if could not (e.g. bad position).
     */
    protected boolean launchSuggestion(int position) {
        return launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
    }
    
    /**
     * Launches an intent based on a suggestion.
     * 
     * @param position The index of the suggestion to create the intent from.
     * @param actionKey The key code of the action key that was pressed,
     *        or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
     * @param actionMsg The message for the action key that was pressed,
     *        or <code>null</code> if none.
     * @return true if a successful launch, false if could not (e.g. bad position).
     */
    protected boolean launchSuggestion(int position, int actionKey, String actionMsg) {
        Cursor c = mSuggestionsAdapter.getCursor();
        if ((c != null) && c.moveToPosition(position)) {

            Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);

            // report back about the click
            if (mGlobalSearchMode) {
                // in global search mode, do it via cursor
                mSuggestionsAdapter.callCursorOnClick(c, position);
            } else if (intent != null
                    && mPreviousComponents != null
                    && !mPreviousComponents.isEmpty()) {
                // in-app search (and we have pivoted in as told by mPreviousComponents,
                // which is used for keeping track of what we pop back to when we are pivoting into
                // in app search.)
                reportInAppClickToGlobalSearch(c, intent);
            }

            // launch the intent
            launchIntent(intent);

            return true;
        }
        return false;
    }

    /**
     * Report a click from an in app search result back to global search for shortcutting porpoises.
     *
     * @param c The cursor that is pointing to the clicked position.
     * @param intent The intent that will be launched for the click.
     */
    private void reportInAppClickToGlobalSearch(Cursor c, Intent intent) {
        // for in app search, still tell global search via content provider
        Uri uri = getClickReportingUri();
        final ContentValues cv = new ContentValues();
        cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_QUERY, mUserQuery);
        final ComponentName source = mSearchable.getSearchActivity();
        cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_COMPONENT, source.flattenToShortString());

        // grab the intent columns from the intent we created since it has additional
        // logic for falling back on the searchable default
        cv.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION, intent.getAction());
        cv.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, intent.getDataString());
        cv.put(SearchManager.SUGGEST_COLUMN_INTENT_COMPONENT_NAME,
                        intent.getStringExtra(SearchManager.COMPONENT_NAME_KEY));

        // ensure the icons will work for global search
        cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
                        wrapIconForPackage(
                                source,
                                getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_1)));
        cv.put(SearchManager.SUGGEST_COLUMN_ICON_2,
                        wrapIconForPackage(
                                source,
                                getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_2)));

        // the rest can be passed through directly
        cv.put(SearchManager.SUGGEST_COLUMN_FORMAT,
                getColumnString(c, SearchManager.SUGGEST_COLUMN_FORMAT));
        cv.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
                getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_1));
        cv.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
                getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_2));
        cv.put(SearchManager.SUGGEST_COLUMN_QUERY,
                getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY));
        cv.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
                getColumnString(c, SearchManager.SUGGEST_COLUMN_SHORTCUT_ID));
        // note: deliberately omitting background color since it is only for global search
        // "more results" entries
        mContext.getContentResolver().insert(uri, cv);
    }

    /**
     * @return A URI appropriate for reporting a click.
     */
    private Uri getClickReportingUri() {
        Uri.Builder uriBuilder = new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(SearchManager.SEARCH_CLICK_REPORT_AUTHORITY);

        uriBuilder.appendPath(SearchManager.SEARCH_CLICK_REPORT_URI_PATH);

        return uriBuilder
                .query("")     // TODO: Remove, workaround for a bug in Uri.writeToParcel()
                .fragment("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
                .build();
    }

    /**
     * Wraps an icon for a particular package.  If the icon is a resource id, it is converted into
     * an android.resource:// URI.
     *
     * @param source The source of the icon
     * @param icon The icon retrieved from a suggestion column
     * @return An icon string appropriate for the package.
     */
    private String wrapIconForPackage(ComponentName source, String icon) {
        if (icon == null || icon.length() == 0 || "0".equals(icon)) {
            // SearchManager specifies that null or zero can be returned to indicate
            // no icon. We also allow empty string.
            return null;
        } else if (!Character.isDigit(icon.charAt(0))){
            return icon;
        } else {
            String packageName = source.getPackageName();
            return new Uri.Builder()
                    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                    .authority(packageName)
                    .encodedPath(icon)
                    .toString();
        }
    }

    /**
     * Launches an intent, including any special intent handling.  Doesn't dismiss the dialog
     * since that will be handled in {@link SearchDialogWrapper#performActivityResuming}
     */
    private void launchIntent(Intent intent) {
        if (intent == null) {
            return;
        }
        if (handleSpecialIntent(intent)){
            return;
        }
        Log.d(LOG_TAG, "launching " + intent);
        try {
            // in global search mode, we send the activity straight to the original suggestion
            // source. this is because GlobalSearch may not have permission to launch the
            // intent, and to avoid the extra step of going through GlobalSearch.
            if (mGlobalSearchMode) {
                launchGlobalSearchIntent(intent);
            } else {
                getContext().startActivity(intent);
                // in global search mode, SearchDialogWrapper#performActivityResuming
                // will handle hiding the dialog when the next activity starts, but for
                // in-app search, we still need to dismiss the dialog.
                dismiss();
            }
        } catch (RuntimeException ex) {
            Log.e(LOG_TAG, "Failed launch activity: " + intent, ex);
        }
    }

    private void launchGlobalSearchIntent(Intent intent) {
        final String packageName;
        // GlobalSearch puts the original source of the suggestion in the
        // 'component name' column. If set, we send the intent to that activity.
        // We trust GlobalSearch to always set this to the suggestion source.
        String intentComponent = intent.getStringExtra(SearchManager.COMPONENT_NAME_KEY);
        if (intentComponent != null) {
            ComponentName componentName = ComponentName.unflattenFromString(intentComponent);
            intent.setComponent(componentName);
            intent.removeExtra(SearchManager.COMPONENT_NAME_KEY);
            // Launch the intent as the suggestion source.
            // This prevents sources from using the search dialog to launch
            // intents that they don't have permission for themselves.
            packageName = componentName.getPackageName();
        } else {
            // If there is no component in the suggestion, it must be a built-in suggestion
            // from GlobalSearch (e.g. "Search the web for") or the intent
            // launched when pressing the search/go button in the search dialog.
            // Launch the intent with the permissions of GlobalSearch.
            packageName = mSearchable.getSearchActivity().getPackageName();
        }

        // Launch all global search suggestions as new tasks, since they don't relate
        // to the current task.
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        setBrowserApplicationId(intent);

        if (DBG) Log.d(LOG_TAG, "Launching intent " + intent.toURI() + " as " + packageName);
        startActivityInPackage(intent, packageName);
    }

    /**
     * If the intent is to open an HTTP or HTTPS URL, we set
     * {@link Browser#EXTRA_APPLICATION_ID} so that any existing browser window that
     * has been opened by us for the same URL will be reused.
     */
    private void setBrowserApplicationId(Intent intent) {
        Uri data = intent.getData();
        if (Intent.ACTION_VIEW.equals(intent.getAction()) && data != null) {
            String scheme = data.getScheme();
            if (scheme != null && scheme.startsWith("http")) {
                intent.putExtra(Browser.EXTRA_APPLICATION_ID, data.toString());
            }
        }
    }

    /**
     * Starts an activity as if it had been started by the given package.
     *
     * @param intent The description of the activity to start.
     * @param packageName
     * @throws ActivityNotFoundException If the intent could not be resolved to
     *         and existing activity.
     * @throws SecurityException If the package does not have permission to start
     *         start the activity.
     * @throws AndroidRuntimeException If some other error occurs.
     */
    private void startActivityInPackage(Intent intent, String packageName) {
        try {
            int uid = ActivityThread.getPackageManager().getPackageUid(packageName);
            if (uid < 0) {
                throw new AndroidRuntimeException("Package UID not found " + packageName);
            }
            String resolvedType = intent.resolveTypeIfNeeded(getContext().getContentResolver());
            IBinder resultTo = null;
            String resultWho = null;
            int requestCode = -1;
            boolean onlyIfNeeded = false;
            int result = ActivityManagerNative.getDefault().startActivityInPackage(
                    uid, intent, resolvedType, resultTo, resultWho, requestCode, onlyIfNeeded);
            checkStartActivityResult(result, intent);
        } catch (RemoteException ex) {
            throw new AndroidRuntimeException(ex);
        }
    }

    // Stolen from Instrumentation.checkStartActivityResult()
    private static void checkStartActivityResult(int res, Intent intent) {
        if (res >= IActivityManager.START_SUCCESS) {
            return;
        }
        switch (res) {
            case IActivityManager.START_INTENT_NOT_RESOLVED:
            case IActivityManager.START_CLASS_NOT_FOUND:
                if (intent.getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + intent.getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case IActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

    /**
     * Handles the special intent actions declared in {@link SearchManager}.
     * 
     * @return <code>true</code> if the intent was handled.
     */
    private boolean handleSpecialIntent(Intent intent) {
        String action = intent.getAction();
        if (SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.equals(action)) {
            handleChangeSourceIntent(intent);
            return true;
        }
        return false;
    }
    
    /**
     * Handles {@link SearchManager#INTENT_ACTION_CHANGE_SEARCH_SOURCE}.
     */
    private void handleChangeSourceIntent(Intent intent) {
        Uri dataUri = intent.getData();
        if (dataUri == null) {
            Log.w(LOG_TAG, "SearchManager.INTENT_ACTION_CHANGE_SOURCE without intent data.");
            return;
        }
        ComponentName componentName = ComponentName.unflattenFromString(dataUri.toString());
        if (componentName == null) {
            Log.w(LOG_TAG, "Invalid ComponentName: " + dataUri);
            return;
        }
        if (DBG) Log.d(LOG_TAG, "Switching to " + componentName);
        
        ComponentName previous = mLaunchComponent;
        if (!show(componentName, mAppSearchData, false)) {
            Log.w(LOG_TAG, "Failed to switch to source " + componentName);
            return;
        }
        pushPreviousComponent(previous);

        String query = intent.getStringExtra(SearchManager.QUERY);
        setUserQuery(query);
        mSearchAutoComplete.showDropDown();
    }

    /**
     * Sets the list item selection in the AutoCompleteTextView's ListView.
     */
    public void setListSelection(int index) {
        mSearchAutoComplete.setListSelection(index);
    }

    /**
     * Saves the previous component that was searched, so that we can go
     * back to it.
     */
    private void pushPreviousComponent(ComponentName componentName) {
        if (mPreviousComponents == null) {
            mPreviousComponents = new ArrayList<ComponentName>();
        }
        mPreviousComponents.add(componentName);
    }
    
    /**
     * Pops the previous component off the stack and returns it.
     * 
     * @return The component name, or <code>null</code> if there was
     *         no previous component.
     */
    private ComponentName popPreviousComponent() {
        if (mPreviousComponents == null) {
            return null;
        }
        int size = mPreviousComponents.size();
        if (size == 0) {
            return null;
        }
        return mPreviousComponents.remove(size - 1);
    }
    
    /**
     * Goes back to the previous component that was searched, if any.
     * 
     * @return <code>true</code> if there was a previous component that we could go back to.
     */
    private boolean backToPreviousComponent() {
        ComponentName previous = popPreviousComponent();
        if (previous == null) {
            return false;
        }
        if (!show(previous, mAppSearchData, false)) {
            Log.w(LOG_TAG, "Failed to switch to source " + previous);
            return false;
        }
        
        // must touch text to trigger suggestions
        // TODO: should this be the text as it was when the user left
        // the source that we are now going back to?
        String query = mSearchAutoComplete.getText().toString();
        setUserQuery(query);
        
        return true;
    }
    
    /**
     * When a particular suggestion has been selected, perform the various lookups required
     * to use the suggestion.  This includes checking the cursor for suggestion-specific data,
     * and/or falling back to the XML for defaults;  It also creates REST style Uri data when
     * the suggestion includes a data id.
     * 
     * @param c The suggestions cursor, moved to the row of the user's selection
     * @param actionKey The key code of the action key that was pressed,
     *        or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
     * @param actionMsg The message for the action key that was pressed,
     *        or <code>null</code> if none.
     * @return An intent for the suggestion at the cursor's position.
     */
    private Intent createIntentFromSuggestion(Cursor c, int actionKey, String actionMsg) {
        try {
            // use specific action if supplied, or default action if supplied, or fixed default
            String action = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_ACTION);

            // some items are display only, or have effect via the cursor respond click reporting.
            if (SearchManager.INTENT_ACTION_NONE.equals(action)) {
                return null;
            }

            if (action == null) {
                action = mSearchable.getSuggestIntentAction();
            }
            if (action == null) {
                action = Intent.ACTION_SEARCH;
            }
            
            // use specific data if supplied, or default data if supplied
            String data = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA);
            if (data == null) {
                data = mSearchable.getSuggestIntentData();
            }
            // then, if an ID was provided, append it.
            if (data != null) {
                String id = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
                if (id != null) {
                    data = data + "/" + Uri.encode(id);
                }
            }
            Uri dataUri = (data == null) ? null : Uri.parse(data);

            String componentName = getColumnString(
                    c, SearchManager.SUGGEST_COLUMN_INTENT_COMPONENT_NAME);

            String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY);
            String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA);

            return createIntent(action, dataUri, extraData, query, componentName, actionKey,
                    actionMsg);
        } catch (RuntimeException e ) {
            int rowNum;
            try {                       // be really paranoid now
                rowNum = c.getPosition();
            } catch (RuntimeException e2 ) {
                rowNum = -1;
            }
            Log.w(LOG_TAG, "Search Suggestions cursor at row " + rowNum + 
                            " returned exception" + e.toString());
            return null;
        }
    }
    
    /**
     * Constructs an intent from the given information and the search dialog state.
     * 
     * @param action Intent action.
     * @param data Intent data, or <code>null</code>.
     * @param extraData Data for {@link SearchManager#EXTRA_DATA_KEY} or <code>null</code>.
     * @param query Intent query, or <code>null</code>.
     * @param componentName Data for {@link SearchManager#COMPONENT_NAME_KEY} or <code>null</code>.
     * @param actionKey The key code of the action key that was pressed,
     *        or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
     * @param actionMsg The message for the action key that was pressed,
     *        or <code>null</code> if none.
     * @return The intent.
     */
    private Intent createIntent(String action, Uri data, String extraData, String query,
            String componentName, int actionKey, String actionMsg) {
        // Now build the Intent
        Intent intent = new Intent(action);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (data != null) {
            intent.setData(data);
        }
        intent.putExtra(SearchManager.USER_QUERY, mUserQuery);
        if (query != null) {
            intent.putExtra(SearchManager.QUERY, query);
        }
        if (extraData != null) {
            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
        }
        if (componentName != null) {
            intent.putExtra(SearchManager.COMPONENT_NAME_KEY, componentName);
        }
        if (mAppSearchData != null) {
            intent.putExtra(SearchManager.APP_DATA, mAppSearchData);
        }
        if (actionKey != KeyEvent.KEYCODE_UNKNOWN) {
            intent.putExtra(SearchManager.ACTION_KEY, actionKey);
            intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
        }
        // Only allow 3rd-party intents from GlobalSearch
        if (!mGlobalSearchMode) {
            intent.setComponent(mSearchable.getSearchActivity());
        }
        return intent;
    }
    
    /**
     * For a given suggestion and a given cursor row, get the action message.  If not provided
     * by the specific row/column, also check for a single definition (for the action key).
     * 
     * @param c The cursor providing suggestions
     * @param actionKey The actionkey record being examined
     * 
     * @return Returns a string, or null if no action key message for this suggestion
     */
    private static String getActionKeyMessage(Cursor c, SearchableInfo.ActionKeyInfo actionKey) {
        String result = null;
        // check first in the cursor data, for a suggestion-specific message
        final String column = actionKey.getSuggestActionMsgColumn();
        if (column != null) {
            result = SuggestionsAdapter.getColumnString(c, column);
        }
        // If the cursor didn't give us a message, see if there's a single message defined
        // for the actionkey (for all suggestions)
        if (result == null) {
            result = actionKey.getSuggestActionMsg();
        }
        return result;
    }
        
    /**
     * Local subclass for AutoCompleteTextView.
     */
    public static class SearchAutoComplete extends AutoCompleteTextView {

        private int mThreshold;
        private SearchDialog mSearchDialog;
        
        public SearchAutoComplete(Context context) {
            super(context);
            mThreshold = getThreshold();
        }
        
        public SearchAutoComplete(Context context, AttributeSet attrs) {
            super(context, attrs);
            mThreshold = getThreshold();
        }

        public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            mThreshold = getThreshold();
        }

        private void setSearchDialog(SearchDialog searchDialog) {
            mSearchDialog = searchDialog;
        }
        
        @Override
        public void setThreshold(int threshold) {
            super.setThreshold(threshold);
            mThreshold = threshold;
        }

        /**
         * Returns true if the text field is empty, or contains only whitespace.
         */
        private boolean isEmpty() {
            return TextUtils.getTrimmedLength(getText()) == 0;
        }

        /**
         * We override this method to avoid replacing the query box text
         * when a suggestion is clicked.
         */
        @Override
        protected void replaceText(CharSequence text) {
        }
        
        /**
         * We override this method to avoid an extra onItemClick being called on the
         * drop-down's OnItemClickListener by {@link AutoCompleteTextView#onKeyUp(int, KeyEvent)}
         * when an item is clicked with the trackball.
         */
        @Override
        public void performCompletion() {
        }

        /**
         * We override this method to be sure and show the soft keyboard if appropriate when
         * the TextView has focus.
         */
        @Override
        public void onWindowFocusChanged(boolean hasWindowFocus) {
            super.onWindowFocusChanged(hasWindowFocus);

            if (hasWindowFocus) {
                InputMethodManager inputManager = (InputMethodManager)
                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                inputManager.showSoftInput(this, 0);
            }
        }
                
        /**
         * We override this method so that we can allow a threshold of zero, which ACTV does not.
         */
        @Override
        public boolean enoughToFilter() {
            return mThreshold <= 0 || super.enoughToFilter();
        }

        /**
         * {@link AutoCompleteTextView#onKeyPreIme(int, KeyEvent)}) dismisses the drop-down on BACK,
         * so we must override this method to modify the BACK behavior.
         */
        @Override
        public boolean onKeyPreIme(int keyCode, KeyEvent event) {
            if (mSearchDialog.mSearchable == null) {
                return false;
            }
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
                if (mSearchDialog.backToPreviousComponent()) {
                    return true;
                }
                return false; // will dismiss soft keyboard if necessary
            }
            return false;
        }
    }
    
    protected boolean handleBackKey(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            if (backToPreviousComponent()) {
                return true;
            }
            cancel();
            return true;
        }
        return false;
    }
    
    /**
     * Implements OnItemClickListener
     */
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (DBG) Log.d(LOG_TAG, "onItemClick() position " + position);
        launchSuggestion(position);
    }

    /** 
     * Implements OnItemSelectedListener
     */
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
         if (DBG) Log.d(LOG_TAG, "onItemSelected() position " + position);
         // A suggestion has been selected, rewrite the query if possible,
         // otherwise the restore the original query.
         if (REWRITE_QUERIES) {
             rewriteQueryFromSuggestion(position);
         }
     }

     /** 
      * Implements OnItemSelectedListener
      */
     public void onNothingSelected(AdapterView<?> parent) {
         if (DBG) Log.d(LOG_TAG, "onNothingSelected()");
     }
     
     /**
      * Query rewriting.
      */

     private void rewriteQueryFromSuggestion(int position) {
         Cursor c = mSuggestionsAdapter.getCursor();
         if (c == null) {
             return;
         }
         if (c.moveToPosition(position)) {
             // Get the new query from the suggestion.
             CharSequence newQuery = mSuggestionsAdapter.convertToString(c);
             if (newQuery != null) {
                 // The suggestion rewrites the query.
                 if (DBG) Log.d(LOG_TAG, "Rewriting query to '" + newQuery + "'");
                 // Update the text field, without getting new suggestions.
                 setQuery(newQuery);
             } else {
                 // The suggestion does not rewrite the query, restore the user's query.
                 if (DBG) Log.d(LOG_TAG, "Suggestion gives no rewrite, restoring user query.");
                 restoreUserQuery();
             }
         } else {
             // We got a bad position, restore the user's query.
             Log.w(LOG_TAG, "Bad suggestion position: " + position);
             restoreUserQuery();
         }
     }
     
     /** 
      * Restores the query entered by the user if needed.
      */
     private void restoreUserQuery() {
         if (DBG) Log.d(LOG_TAG, "Restoring query to '" + mUserQuery + "'");
         setQuery(mUserQuery);
     }
     
     /**
      * Sets the text in the query box, without updating the suggestions.
      */
     private void setQuery(CharSequence query) {
         mSearchAutoComplete.setText(query, false);
         if (query != null) {
             mSearchAutoComplete.setSelection(query.length());
         }
     }
     
     /**
      * Sets the text in the query box, updating the suggestions.
      */
     private void setUserQuery(String query) {
         if (query == null) {
             query = "";
         }
         mUserQuery = query;
         mSearchAutoComplete.setText(query);
         mSearchAutoComplete.setSelection(query.length());
     }

    /**
     * Debugging Support
     */

    /**
     * For debugging only, sample the millisecond clock and log it.
     * Uses AtomicLong so we can use in multiple threads
     */
    private AtomicLong mLastLogTime = new AtomicLong(SystemClock.uptimeMillis());
    private void dbgLogTiming(final String caller) {
        long millis = SystemClock.uptimeMillis();
        long oldTime = mLastLogTime.getAndSet(millis);
        long delta = millis - oldTime;
        final String report = millis + " (+" + delta + ") ticks for Search keystroke in " + caller;
        Log.d(LOG_TAG,report);
    }
}
