Source code
package android.support.v7.widget;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.app.SearchableInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.support.v4.view.KeyEventCompat;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.appcompat.R;
import android.support.v7.internal.widget.TintManager;
import android.support.v7.internal.widget.TintTypedArray;
import android.support.v7.internal.widget.ViewUtils;
import android.support.v7.view.CollapsibleActionView;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.KeyEvent.DispatcherState;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import java.lang.reflect.Method;
import java.util.WeakHashMap;
public class SearchView extends LinearLayoutCompat implements CollapsibleActionView {
private static final boolean DBG = false;
static final AutoCompleteTextViewReflector HIDDEN_METHOD_INVOKER = new AutoCompleteTextViewReflector();
private static final String IME_OPTION_NO_MICROPHONE = "nm";
private static final boolean IS_AT_LEAST_FROYO;
private static final String LOG_TAG = "SearchView";
private Bundle mAppSearchData;
private boolean mClearingFocus;
private final ImageView mCloseButton;
private final ImageView mCollapsedIcon;
private int mCollapsedImeOptions;
private final CharSequence mDefaultQueryHint;
private final View mDropDownAnchor;
private boolean mExpandedInActionView;
private final ImageView mGoButton;
private boolean mIconified;
private boolean mIconifiedByDefault;
private int mMaxWidth;
private CharSequence mOldQueryText;
private final OnClickListener mOnClickListener;
private OnCloseListener mOnCloseListener;
private final OnEditorActionListener mOnEditorActionListener;
private final OnItemClickListener mOnItemClickListener;
private final OnItemSelectedListener mOnItemSelectedListener;
private OnQueryTextListener mOnQueryChangeListener;
private OnFocusChangeListener mOnQueryTextFocusChangeListener;
private OnClickListener mOnSearchClickListener;
private OnSuggestionListener mOnSuggestionListener;
private final WeakHashMap<String, ConstantState> mOutsideDrawablesCache;
private CharSequence mQueryHint;
private boolean mQueryRefinement;
private Runnable mReleaseCursorRunnable;
private final ImageView mSearchButton;
private final View mSearchEditFrame;
private final Drawable mSearchHintIcon;
private final View mSearchPlate;
private final SearchAutoComplete mSearchSrcTextView;
private SearchableInfo mSearchable;
private Runnable mShowImeRunnable;
private final View mSubmitArea;
private boolean mSubmitButtonEnabled;
private final int mSuggestionCommitIconResId;
private final int mSuggestionRowLayout;
private CursorAdapter mSuggestionsAdapter;
OnKeyListener mTextKeyListener;
private TextWatcher mTextWatcher;
private final TintManager mTintManager;
private final Runnable mUpdateDrawableStateRunnable;
private CharSequence mUserQuery;
private final Intent mVoiceAppSearchIntent;
private final ImageView mVoiceButton;
private boolean mVoiceButtonEnabled;
private final Intent mVoiceWebSearchIntent;
private static class AutoCompleteTextViewReflector {
private Method doAfterTextChanged;
private Method doBeforeTextChanged;
private Method ensureImeVisible;
private Method showSoftInputUnchecked;
AutoCompleteTextViewReflector() {
try {
this.doBeforeTextChanged = AutoCompleteTextView.class.getDeclaredMethod("doBeforeTextChanged", new Class[0]);
this.doBeforeTextChanged.setAccessible(true);
} catch (NoSuchMethodException e) {
}
try {
this.doAfterTextChanged = AutoCompleteTextView.class.getDeclaredMethod("doAfterTextChanged", new Class[0]);
this.doAfterTextChanged.setAccessible(true);
} catch (NoSuchMethodException e2) {
}
try {
this.ensureImeVisible = AutoCompleteTextView.class.getMethod("ensureImeVisible", new Class[]{Boolean.TYPE});
this.ensureImeVisible.setAccessible(true);
} catch (NoSuchMethodException e3) {
}
try {
this.showSoftInputUnchecked = InputMethodManager.class.getMethod("showSoftInputUnchecked", new Class[]{Integer.TYPE, ResultReceiver.class});
this.showSoftInputUnchecked.setAccessible(true);
} catch (NoSuchMethodException e4) {
}
}
void doBeforeTextChanged(AutoCompleteTextView view) {
if (this.doBeforeTextChanged != null) {
try {
this.doBeforeTextChanged.invoke(view, new Object[0]);
} catch (Exception e) {
}
}
}
void doAfterTextChanged(AutoCompleteTextView view) {
if (this.doAfterTextChanged != null) {
try {
this.doAfterTextChanged.invoke(view, new Object[0]);
} catch (Exception e) {
}
}
}
void ensureImeVisible(AutoCompleteTextView view, boolean visible) {
if (this.ensureImeVisible != null) {
try {
this.ensureImeVisible.invoke(view, new Object[]{Boolean.valueOf(visible)});
} catch (Exception e) {
}
}
}
void showSoftInputUnchecked(InputMethodManager imm, View view, int flags) {
if (this.showSoftInputUnchecked != null) {
try {
this.showSoftInputUnchecked.invoke(imm, new Object[]{Integer.valueOf(flags), null});
return;
} catch (Exception e) {
}
}
imm.showSoftInput(view, flags);
}
}
public interface OnCloseListener {
boolean onClose();
}
public interface OnQueryTextListener {
boolean onQueryTextChange(String str);
boolean onQueryTextSubmit(String str);
}
public interface OnSuggestionListener {
boolean onSuggestionClick(int i);
boolean onSuggestionSelect(int i);
}
public static class SearchAutoComplete extends AppCompatAutoCompleteTextView {
private SearchView mSearchView;
private int mThreshold;
public SearchAutoComplete(Context context) {
this(context, null);
}
public SearchAutoComplete(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.autoCompleteTextViewStyle);
}
public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mThreshold = getThreshold();
}
void setSearchView(SearchView searchView) {
this.mSearchView = searchView;
}
public void setThreshold(int threshold) {
super.setThreshold(threshold);
this.mThreshold = threshold;
}
private boolean isEmpty() {
return TextUtils.getTrimmedLength(getText()) == 0;
}
protected void replaceText(CharSequence text) {
}
public void performCompletion() {
}
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus && this.mSearchView.hasFocus() && getVisibility() == 0) {
((InputMethodManager) getContext().getSystemService("input_method")).showSoftInput(this, 0);
if (SearchView.isLandscapeMode(getContext())) {
SearchView.HIDDEN_METHOD_INVOKER.ensureImeVisible(this, true);
}
}
}
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
this.mSearchView.onTextFocusChanged();
}
public boolean enoughToFilter() {
return this.mThreshold <= 0 || super.enoughToFilter();
}
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == 4) {
DispatcherState state;
if (event.getAction() == 0 && event.getRepeatCount() == 0) {
state = getKeyDispatcherState();
if (state == null) {
return true;
}
state.startTracking(event, this);
return true;
} else if (event.getAction() == 1) {
state = getKeyDispatcherState();
if (state != null) {
state.handleUpEvent(event);
}
if (event.isTracking() && !event.isCanceled()) {
this.mSearchView.clearFocus();
this.mSearchView.setImeVisibility(false);
return true;
}
}
}
return super.onKeyPreIme(keyCode, event);
}
}
static {
boolean z;
if (VERSION.SDK_INT >= 8) {
z = true;
} else {
z = false;
}
IS_AT_LEAST_FROYO = z;
}
public SearchView(Context context) {
this(context, null);
}
public SearchView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.searchViewStyle);
}
public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mShowImeRunnable = new Runnable() {
public void run() {
InputMethodManager imm = (InputMethodManager) SearchView.this.getContext().getSystemService("input_method");
if (imm != null) {
SearchView.HIDDEN_METHOD_INVOKER.showSoftInputUnchecked(imm, SearchView.this, 0);
}
}
};
this.mUpdateDrawableStateRunnable = new Runnable() {
public void run() {
SearchView.this.updateFocusedState();
}
};
this.mReleaseCursorRunnable = new Runnable() {
public void run() {
if (SearchView.this.mSuggestionsAdapter != null && (SearchView.this.mSuggestionsAdapter instanceof SuggestionsAdapter)) {
SearchView.this.mSuggestionsAdapter.changeCursor(null);
}
}
};
this.mOutsideDrawablesCache = new WeakHashMap();
this.mOnClickListener = new OnClickListener() {
public void onClick(View v) {
if (v == SearchView.this.mSearchButton) {
SearchView.this.onSearchClicked();
} else if (v == SearchView.this.mCloseButton) {
SearchView.this.onCloseClicked();
} else if (v == SearchView.this.mGoButton) {
SearchView.this.onSubmitQuery();
} else if (v == SearchView.this.mVoiceButton) {
SearchView.this.onVoiceClicked();
} else if (v == SearchView.this.mSearchSrcTextView) {
SearchView.this.forceSuggestionQuery();
}
}
};
this.mTextKeyListener = new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (SearchView.this.mSearchable == null) {
return false;
}
if (SearchView.this.mSearchSrcTextView.isPopupShowing() && SearchView.this.mSearchSrcTextView.getListSelection() != -1) {
return SearchView.this.onSuggestionsKey(v, keyCode, event);
}
if (SearchView.this.mSearchSrcTextView.isEmpty() || !KeyEventCompat.hasNoModifiers(event) || event.getAction() != 1 || keyCode != 66) {
return false;
}
v.cancelLongPress();
SearchView.this.launchQuerySearch(0, null, SearchView.this.mSearchSrcTextView.getText().toString());
return true;
}
};
this.mOnEditorActionListener = new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
SearchView.this.onSubmitQuery();
return true;
}
};
this.mOnItemClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
SearchView.this.onItemClicked(position, 0, null);
}
};
this.mOnItemSelectedListener = new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
SearchView.this.onItemSelected(position);
}
public void onNothingSelected(AdapterView<?> adapterView) {
}
};
this.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) {
SearchView.this.onTextChanged(s);
}
public void afterTextChanged(Editable s) {
}
};
TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.SearchView, defStyleAttr, 0);
this.mTintManager = a.getTintManager();
LayoutInflater.from(context).inflate(a.getResourceId(R.styleable.SearchView_layout, R.layout.abc_search_view), this, true);
this.mSearchSrcTextView = (SearchAutoComplete) findViewById(R.id.search_src_text);
this.mSearchSrcTextView.setSearchView(this);
this.mSearchEditFrame = findViewById(R.id.search_edit_frame);
this.mSearchPlate = findViewById(R.id.search_plate);
this.mSubmitArea = findViewById(R.id.submit_area);
this.mSearchButton = (ImageView) findViewById(R.id.search_button);
this.mGoButton = (ImageView) findViewById(R.id.search_go_btn);
this.mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
this.mVoiceButton = (ImageView) findViewById(R.id.search_voice_btn);
this.mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
this.mSearchPlate.setBackgroundDrawable(a.getDrawable(R.styleable.SearchView_queryBackground));
this.mSubmitArea.setBackgroundDrawable(a.getDrawable(R.styleable.SearchView_submitBackground));
this.mSearchButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_searchIcon));
this.mGoButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_goIcon));
this.mCloseButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_closeIcon));
this.mVoiceButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_voiceIcon));
this.mCollapsedIcon.setImageDrawable(a.getDrawable(R.styleable.SearchView_searchIcon));
this.mSearchHintIcon = a.getDrawable(R.styleable.SearchView_searchHintIcon);
this.mSuggestionRowLayout = a.getResourceId(R.styleable.SearchView_suggestionRowLayout, R.layout.abc_search_dropdown_item_icons_2line);
this.mSuggestionCommitIconResId = a.getResourceId(R.styleable.SearchView_commitIcon, 0);
this.mSearchButton.setOnClickListener(this.mOnClickListener);
this.mCloseButton.setOnClickListener(this.mOnClickListener);
this.mGoButton.setOnClickListener(this.mOnClickListener);
this.mVoiceButton.setOnClickListener(this.mOnClickListener);
this.mSearchSrcTextView.setOnClickListener(this.mOnClickListener);
this.mSearchSrcTextView.addTextChangedListener(this.mTextWatcher);
this.mSearchSrcTextView.setOnEditorActionListener(this.mOnEditorActionListener);
this.mSearchSrcTextView.setOnItemClickListener(this.mOnItemClickListener);
this.mSearchSrcTextView.setOnItemSelectedListener(this.mOnItemSelectedListener);
this.mSearchSrcTextView.setOnKeyListener(this.mTextKeyListener);
this.mSearchSrcTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (SearchView.this.mOnQueryTextFocusChangeListener != null) {
SearchView.this.mOnQueryTextFocusChangeListener.onFocusChange(SearchView.this, hasFocus);
}
}
});
setIconifiedByDefault(a.getBoolean(R.styleable.SearchView_iconifiedByDefault, true));
int maxWidth = a.getDimensionPixelSize(R.styleable.SearchView_android_maxWidth, -1);
if (maxWidth != -1) {
setMaxWidth(maxWidth);
}
this.mDefaultQueryHint = a.getText(R.styleable.SearchView_defaultQueryHint);
this.mQueryHint = a.getText(R.styleable.SearchView_queryHint);
int imeOptions = a.getInt(R.styleable.SearchView_android_imeOptions, -1);
if (imeOptions != -1) {
setImeOptions(imeOptions);
}
int inputType = a.getInt(R.styleable.SearchView_android_inputType, -1);
if (inputType != -1) {
setInputType(inputType);
}
setFocusable(a.getBoolean(R.styleable.SearchView_android_focusable, true));
a.recycle();
this.mVoiceWebSearchIntent = new Intent("android.speech.action.WEB_SEARCH");
this.mVoiceWebSearchIntent.addFlags(268435456);
this.mVoiceWebSearchIntent.putExtra("android.speech.extra.LANGUAGE_MODEL", "web_search");
this.mVoiceAppSearchIntent = new Intent("android.speech.action.RECOGNIZE_SPEECH");
this.mVoiceAppSearchIntent.addFlags(268435456);
this.mDropDownAnchor = findViewById(this.mSearchSrcTextView.getDropDownAnchor());
if (this.mDropDownAnchor != null) {
if (VERSION.SDK_INT >= 11) {
addOnLayoutChangeListenerToDropDownAnchorSDK11();
} else {
addOnLayoutChangeListenerToDropDownAnchorBase();
}
}
updateViewsVisibility(this.mIconifiedByDefault);
updateQueryHint();
}
@TargetApi(11)
private void addOnLayoutChangeListenerToDropDownAnchorSDK11() {
this.mDropDownAnchor.addOnLayoutChangeListener(new OnLayoutChangeListener() {
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
SearchView.this.adjustDropDownSizeAndPosition();
}
});
}
private void addOnLayoutChangeListenerToDropDownAnchorBase() {
this.mDropDownAnchor.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
SearchView.this.adjustDropDownSizeAndPosition();
}
});
}
int getSuggestionRowLayout() {
return this.mSuggestionRowLayout;
}
int getSuggestionCommitIconResId() {
return this.mSuggestionCommitIconResId;
}
public void setSearchableInfo(SearchableInfo searchable) {
this.mSearchable = searchable;
if (this.mSearchable != null) {
if (IS_AT_LEAST_FROYO) {
updateSearchAutoComplete();
}
updateQueryHint();
}
boolean z = IS_AT_LEAST_FROYO && hasVoiceSearch();
this.mVoiceButtonEnabled = z;
if (this.mVoiceButtonEnabled) {
this.mSearchSrcTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE);
}
updateViewsVisibility(isIconified());
}
public void setAppSearchData(Bundle appSearchData) {
this.mAppSearchData = appSearchData;
}
public void setImeOptions(int imeOptions) {
this.mSearchSrcTextView.setImeOptions(imeOptions);
}
public int getImeOptions() {
return this.mSearchSrcTextView.getImeOptions();
}
public void setInputType(int inputType) {
this.mSearchSrcTextView.setInputType(inputType);
}
public int getInputType() {
return this.mSearchSrcTextView.getInputType();
}
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
if (this.mClearingFocus) {
return false;
}
if (!isFocusable()) {
return false;
}
if (isIconified()) {
return super.requestFocus(direction, previouslyFocusedRect);
}
boolean result = this.mSearchSrcTextView.requestFocus(direction, previouslyFocusedRect);
if (!result) {
return result;
}
updateViewsVisibility(false);
return result;
}
public void clearFocus() {
this.mClearingFocus = true;
setImeVisibility(false);
super.clearFocus();
this.mSearchSrcTextView.clearFocus();
this.mClearingFocus = false;
}
public void setOnQueryTextListener(OnQueryTextListener listener) {
this.mOnQueryChangeListener = listener;
}
public void setOnCloseListener(OnCloseListener listener) {
this.mOnCloseListener = listener;
}
public void setOnQueryTextFocusChangeListener(OnFocusChangeListener listener) {
this.mOnQueryTextFocusChangeListener = listener;
}
public void setOnSuggestionListener(OnSuggestionListener listener) {
this.mOnSuggestionListener = listener;
}
public void setOnSearchClickListener(OnClickListener listener) {
this.mOnSearchClickListener = listener;
}
public CharSequence getQuery() {
return this.mSearchSrcTextView.getText();
}
public void setQuery(CharSequence query, boolean submit) {
this.mSearchSrcTextView.setText(query);
if (query != null) {
this.mSearchSrcTextView.setSelection(this.mSearchSrcTextView.length());
this.mUserQuery = query;
}
if (submit && !TextUtils.isEmpty(query)) {
onSubmitQuery();
}
}
public void setQueryHint(CharSequence hint) {
this.mQueryHint = hint;
updateQueryHint();
}
public CharSequence getQueryHint() {
if (this.mQueryHint != null) {
return this.mQueryHint;
}
if (!IS_AT_LEAST_FROYO || this.mSearchable == null || this.mSearchable.getHintId() == 0) {
return this.mDefaultQueryHint;
}
return getContext().getText(this.mSearchable.getHintId());
}
public void setIconifiedByDefault(boolean iconified) {
if (this.mIconifiedByDefault != iconified) {
this.mIconifiedByDefault = iconified;
updateViewsVisibility(iconified);
updateQueryHint();
}
}
public boolean isIconfiedByDefault() {
return this.mIconifiedByDefault;
}
public void setIconified(boolean iconify) {
if (iconify) {
onCloseClicked();
} else {
onSearchClicked();
}
}
public boolean isIconified() {
return this.mIconified;
}
public void setSubmitButtonEnabled(boolean enabled) {
this.mSubmitButtonEnabled = enabled;
updateViewsVisibility(isIconified());
}
public boolean isSubmitButtonEnabled() {
return this.mSubmitButtonEnabled;
}
public void setQueryRefinementEnabled(boolean enable) {
this.mQueryRefinement = enable;
if (this.mSuggestionsAdapter instanceof SuggestionsAdapter) {
((SuggestionsAdapter) this.mSuggestionsAdapter).setQueryRefinement(enable ? 2 : 1);
}
}
public boolean isQueryRefinementEnabled() {
return this.mQueryRefinement;
}
public void setSuggestionsAdapter(CursorAdapter adapter) {
this.mSuggestionsAdapter = adapter;
this.mSearchSrcTextView.setAdapter(this.mSuggestionsAdapter);
}
public CursorAdapter getSuggestionsAdapter() {
return this.mSuggestionsAdapter;
}
public void setMaxWidth(int maxpixels) {
this.mMaxWidth = maxpixels;
requestLayout();
}
public int getMaxWidth() {
return this.mMaxWidth;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isIconified()) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
switch (widthMode) {
case Integer.MIN_VALUE:
if (this.mMaxWidth <= 0) {
width = Math.min(getPreferredWidth(), width);
break;
} else {
width = Math.min(this.mMaxWidth, width);
break;
}
case 0:
width = this.mMaxWidth > 0 ? this.mMaxWidth : getPreferredWidth();
break;
case 1073741824:
if (this.mMaxWidth > 0) {
width = Math.min(this.mMaxWidth, width);
break;
}
break;
}
super.onMeasure(MeasureSpec.makeMeasureSpec(width, 1073741824), heightMeasureSpec);
}
private int getPreferredWidth() {
return getContext().getResources().getDimensionPixelSize(R.dimen.abc_search_view_preferred_width);
}
private void updateViewsVisibility(boolean collapsed) {
int visCollapsed;
boolean hasText;
int iconVisibility;
int i = 8;
boolean z = true;
this.mIconified = collapsed;
if (collapsed) {
visCollapsed = 0;
} else {
visCollapsed = 8;
}
if (TextUtils.isEmpty(this.mSearchSrcTextView.getText())) {
hasText = false;
} else {
hasText = true;
}
this.mSearchButton.setVisibility(visCollapsed);
updateSubmitButton(hasText);
View view = this.mSearchEditFrame;
if (!collapsed) {
i = 0;
}
view.setVisibility(i);
if (this.mCollapsedIcon.getDrawable() == null || this.mIconifiedByDefault) {
iconVisibility = 8;
} else {
iconVisibility = 0;
}
this.mCollapsedIcon.setVisibility(iconVisibility);
updateCloseButton();
if (hasText) {
z = false;
}
updateVoiceButton(z);
updateSubmitArea();
}
@TargetApi(8)
private boolean hasVoiceSearch() {
if (this.mSearchable == null || !this.mSearchable.getVoiceSearchEnabled()) {
return false;
}
Intent testIntent = null;
if (this.mSearchable.getVoiceSearchLaunchWebSearch()) {
testIntent = this.mVoiceWebSearchIntent;
} else if (this.mSearchable.getVoiceSearchLaunchRecognizer()) {
testIntent = this.mVoiceAppSearchIntent;
}
if (testIntent == null || getContext().getPackageManager().resolveActivity(testIntent, 65536) == null) {
return false;
}
return true;
}
private boolean isSubmitAreaEnabled() {
return (this.mSubmitButtonEnabled || this.mVoiceButtonEnabled) && !isIconified();
}
private void updateSubmitButton(boolean hasText) {
int visibility = 8;
if (this.mSubmitButtonEnabled && isSubmitAreaEnabled() && hasFocus() && (hasText || !this.mVoiceButtonEnabled)) {
visibility = 0;
}
this.mGoButton.setVisibility(visibility);
}
private void updateSubmitArea() {
int visibility = 8;
if (isSubmitAreaEnabled() && (this.mGoButton.getVisibility() == 0 || this.mVoiceButton.getVisibility() == 0)) {
visibility = 0;
}
this.mSubmitArea.setVisibility(visibility);
}
private void updateCloseButton() {
boolean hasText;
boolean showClose = true;
int i = 0;
if (TextUtils.isEmpty(this.mSearchSrcTextView.getText())) {
hasText = false;
} else {
hasText = true;
}
if (!hasText && (!this.mIconifiedByDefault || this.mExpandedInActionView)) {
showClose = false;
}
ImageView imageView = this.mCloseButton;
if (!showClose) {
i = 8;
}
imageView.setVisibility(i);
Drawable closeButtonImg = this.mCloseButton.getDrawable();
if (closeButtonImg != null) {
closeButtonImg.setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET);
}
}
private void postUpdateFocusedState() {
post(this.mUpdateDrawableStateRunnable);
}
private void updateFocusedState() {
int[] stateSet = this.mSearchSrcTextView.hasFocus() ? FOCUSED_STATE_SET : EMPTY_STATE_SET;
Drawable searchPlateBg = this.mSearchPlate.getBackground();
if (searchPlateBg != null) {
searchPlateBg.setState(stateSet);
}
Drawable submitAreaBg = this.mSubmitArea.getBackground();
if (submitAreaBg != null) {
submitAreaBg.setState(stateSet);
}
invalidate();
}
protected void onDetachedFromWindow() {
removeCallbacks(this.mUpdateDrawableStateRunnable);
post(this.mReleaseCursorRunnable);
super.onDetachedFromWindow();
}
private void setImeVisibility(boolean visible) {
if (visible) {
post(this.mShowImeRunnable);
return;
}
removeCallbacks(this.mShowImeRunnable);
InputMethodManager imm = (InputMethodManager) getContext().getSystemService("input_method");
if (imm != null) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
}
void onQueryRefine(CharSequence queryText) {
setQuery(queryText);
}
private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) {
if (this.mSearchable == null || this.mSuggestionsAdapter == null || event.getAction() != 0 || !KeyEventCompat.hasNoModifiers(event)) {
return false;
}
if (keyCode == 66 || keyCode == 84 || keyCode == 61) {
return onItemClicked(this.mSearchSrcTextView.getListSelection(), 0, null);
}
if (keyCode != 21 && keyCode != 22) {
return (keyCode == 19 && this.mSearchSrcTextView.getListSelection() == 0) ? false : false;
} else {
int selPoint;
if (keyCode == 21) {
selPoint = 0;
} else {
selPoint = this.mSearchSrcTextView.length();
}
this.mSearchSrcTextView.setSelection(selPoint);
this.mSearchSrcTextView.setListSelection(0);
this.mSearchSrcTextView.clearListSelection();
HIDDEN_METHOD_INVOKER.ensureImeVisible(this.mSearchSrcTextView, true);
return true;
}
}
private CharSequence getDecoratedHint(CharSequence hintText) {
if (!this.mIconifiedByDefault || this.mSearchHintIcon == null) {
return hintText;
}
int textSize = (int) (((double) this.mSearchSrcTextView.getTextSize()) * 1.25d);
this.mSearchHintIcon.setBounds(0, 0, textSize, textSize);
CharSequence ssb = new SpannableStringBuilder(" ");
ssb.setSpan(new ImageSpan(this.mSearchHintIcon), 1, 2, 33);
ssb.append(hintText);
return ssb;
}
private void updateQueryHint() {
CharSequence hint = getQueryHint();
SearchAutoComplete searchAutoComplete = this.mSearchSrcTextView;
if (hint == null) {
hint = "";
}
searchAutoComplete.setHint(getDecoratedHint(hint));
}
@TargetApi(8)
private void updateSearchAutoComplete() {
int i = 1;
this.mSearchSrcTextView.setThreshold(this.mSearchable.getSuggestThreshold());
this.mSearchSrcTextView.setImeOptions(this.mSearchable.getImeOptions());
int inputType = this.mSearchable.getInputType();
if ((inputType & 15) == 1) {
inputType &= -65537;
if (this.mSearchable.getSuggestAuthority() != null) {
inputType = (inputType | 65536) | 524288;
}
}
this.mSearchSrcTextView.setInputType(inputType);
if (this.mSuggestionsAdapter != null) {
this.mSuggestionsAdapter.changeCursor(null);
}
if (this.mSearchable.getSuggestAuthority() != null) {
this.mSuggestionsAdapter = new SuggestionsAdapter(getContext(), this, this.mSearchable, this.mOutsideDrawablesCache);
this.mSearchSrcTextView.setAdapter(this.mSuggestionsAdapter);
SuggestionsAdapter suggestionsAdapter = (SuggestionsAdapter) this.mSuggestionsAdapter;
if (this.mQueryRefinement) {
i = 2;
}
suggestionsAdapter.setQueryRefinement(i);
}
}
private void updateVoiceButton(boolean empty) {
int visibility = 8;
if (this.mVoiceButtonEnabled && !isIconified() && empty) {
visibility = 0;
this.mGoButton.setVisibility(8);
}
this.mVoiceButton.setVisibility(visibility);
}
private void onTextChanged(CharSequence newText) {
boolean hasText;
boolean z = true;
CharSequence text = this.mSearchSrcTextView.getText();
this.mUserQuery = text;
if (TextUtils.isEmpty(text)) {
hasText = false;
} else {
hasText = true;
}
updateSubmitButton(hasText);
if (hasText) {
z = false;
}
updateVoiceButton(z);
updateCloseButton();
updateSubmitArea();
if (!(this.mOnQueryChangeListener == null || TextUtils.equals(newText, this.mOldQueryText))) {
this.mOnQueryChangeListener.onQueryTextChange(newText.toString());
}
this.mOldQueryText = newText.toString();
}
private void onSubmitQuery() {
CharSequence query = this.mSearchSrcTextView.getText();
if (query != null && TextUtils.getTrimmedLength(query) > 0) {
if (this.mOnQueryChangeListener == null || !this.mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
if (this.mSearchable != null) {
launchQuerySearch(0, null, query.toString());
}
setImeVisibility(false);
dismissSuggestions();
}
}
}
private void dismissSuggestions() {
this.mSearchSrcTextView.dismissDropDown();
}
private void onCloseClicked() {
if (!TextUtils.isEmpty(this.mSearchSrcTextView.getText())) {
this.mSearchSrcTextView.setText("");
this.mSearchSrcTextView.requestFocus();
setImeVisibility(true);
} else if (!this.mIconifiedByDefault) {
} else {
if (this.mOnCloseListener == null || !this.mOnCloseListener.onClose()) {
clearFocus();
updateViewsVisibility(true);
}
}
}
private void onSearchClicked() {
updateViewsVisibility(false);
this.mSearchSrcTextView.requestFocus();
setImeVisibility(true);
if (this.mOnSearchClickListener != null) {
this.mOnSearchClickListener.onClick(this);
}
}
@TargetApi(8)
private void onVoiceClicked() {
if (this.mSearchable != null) {
SearchableInfo searchable = this.mSearchable;
try {
if (searchable.getVoiceSearchLaunchWebSearch()) {
getContext().startActivity(createVoiceWebSearchIntent(this.mVoiceWebSearchIntent, searchable));
} else if (searchable.getVoiceSearchLaunchRecognizer()) {
getContext().startActivity(createVoiceAppSearchIntent(this.mVoiceAppSearchIntent, searchable));
}
} catch (ActivityNotFoundException e) {
Log.w(LOG_TAG, "Could not find voice search activity");
}
}
}
void onTextFocusChanged() {
updateViewsVisibility(isIconified());
postUpdateFocusedState();
if (this.mSearchSrcTextView.hasFocus()) {
forceSuggestionQuery();
}
}
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
postUpdateFocusedState();
}
public void onActionViewCollapsed() {
setQuery("", false);
clearFocus();
updateViewsVisibility(true);
this.mSearchSrcTextView.setImeOptions(this.mCollapsedImeOptions);
this.mExpandedInActionView = false;
}
public void onActionViewExpanded() {
if (!this.mExpandedInActionView) {
this.mExpandedInActionView = true;
this.mCollapsedImeOptions = this.mSearchSrcTextView.getImeOptions();
this.mSearchSrcTextView.setImeOptions(this.mCollapsedImeOptions | 33554432);
this.mSearchSrcTextView.setText("");
setIconified(false);
}
}
private void adjustDropDownSizeAndPosition() {
if (this.mDropDownAnchor.getWidth() > 1) {
int offset;
Resources res = getContext().getResources();
int anchorPadding = this.mSearchPlate.getPaddingLeft();
Rect dropDownPadding = new Rect();
boolean isLayoutRtl = ViewUtils.isLayoutRtl(this);
int iconOffset = this.mIconifiedByDefault ? res.getDimensionPixelSize(R.dimen.abc_dropdownitem_icon_width) + res.getDimensionPixelSize(R.dimen.abc_dropdownitem_text_padding_left) : 0;
this.mSearchSrcTextView.getDropDownBackground().getPadding(dropDownPadding);
if (isLayoutRtl) {
offset = -dropDownPadding.left;
} else {
offset = anchorPadding - (dropDownPadding.left + iconOffset);
}
this.mSearchSrcTextView.setDropDownHorizontalOffset(offset);
this.mSearchSrcTextView.setDropDownWidth((((this.mDropDownAnchor.getWidth() + dropDownPadding.left) + dropDownPadding.right) + iconOffset) - anchorPadding);
}
}
private boolean onItemClicked(int position, int actionKey, String actionMsg) {
if (this.mOnSuggestionListener != null && this.mOnSuggestionListener.onSuggestionClick(position)) {
return false;
}
launchSuggestion(position, 0, null);
setImeVisibility(false);
dismissSuggestions();
return true;
}
private boolean onItemSelected(int position) {
if (this.mOnSuggestionListener != null && this.mOnSuggestionListener.onSuggestionSelect(position)) {
return false;
}
rewriteQueryFromSuggestion(position);
return true;
}
private void rewriteQueryFromSuggestion(int position) {
CharSequence oldQuery = this.mSearchSrcTextView.getText();
Cursor c = this.mSuggestionsAdapter.getCursor();
if (c != null) {
if (c.moveToPosition(position)) {
CharSequence newQuery = this.mSuggestionsAdapter.convertToString(c);
if (newQuery != null) {
setQuery(newQuery);
return;
} else {
setQuery(oldQuery);
return;
}
}
setQuery(oldQuery);
}
}
private boolean launchSuggestion(int position, int actionKey, String actionMsg) {
Cursor c = this.mSuggestionsAdapter.getCursor();
if (c == null || !c.moveToPosition(position)) {
return false;
}
launchIntent(createIntentFromSuggestion(c, actionKey, actionMsg));
return true;
}
private void launchIntent(Intent intent) {
if (intent != null) {
try {
getContext().startActivity(intent);
} catch (RuntimeException ex) {
Log.e(LOG_TAG, "Failed launch activity: " + intent, ex);
}
}
}
private void setQuery(CharSequence query) {
this.mSearchSrcTextView.setText(query);
this.mSearchSrcTextView.setSelection(TextUtils.isEmpty(query) ? 0 : query.length());
}
private void launchQuerySearch(int actionKey, String actionMsg, String query) {
getContext().startActivity(createIntent("android.intent.action.SEARCH", null, null, query, actionKey, actionMsg));
}
private Intent createIntent(String action, Uri data, String extraData, String query, int actionKey, String actionMsg) {
Intent intent = new Intent(action);
intent.addFlags(268435456);
if (data != null) {
intent.setData(data);
}
intent.putExtra("user_query", this.mUserQuery);
if (query != null) {
intent.putExtra("query", query);
}
if (extraData != null) {
intent.putExtra("intent_extra_data_key", extraData);
}
if (this.mAppSearchData != null) {
intent.putExtra("app_data", this.mAppSearchData);
}
if (actionKey != 0) {
intent.putExtra("action_key", actionKey);
intent.putExtra("action_msg", actionMsg);
}
if (IS_AT_LEAST_FROYO) {
intent.setComponent(this.mSearchable.getSearchActivity());
}
return intent;
}
@TargetApi(8)
private Intent createVoiceWebSearchIntent(Intent baseIntent, SearchableInfo searchable) {
Intent voiceIntent = new Intent(baseIntent);
ComponentName searchActivity = searchable.getSearchActivity();
voiceIntent.putExtra("calling_package", searchActivity == null ? null : searchActivity.flattenToShortString());
return voiceIntent;
}
@TargetApi(8)
private Intent createVoiceAppSearchIntent(Intent baseIntent, SearchableInfo searchable) {
ComponentName searchActivity = searchable.getSearchActivity();
Intent queryIntent = new Intent("android.intent.action.SEARCH");
queryIntent.setComponent(searchActivity);
PendingIntent pending = PendingIntent.getActivity(getContext(), 0, queryIntent, 1073741824);
Bundle queryExtras = new Bundle();
if (this.mAppSearchData != null) {
queryExtras.putParcelable("app_data", this.mAppSearchData);
}
Intent voiceIntent = new Intent(baseIntent);
String languageModel = "free_form";
String prompt = null;
String language = null;
int maxResults = 1;
if (VERSION.SDK_INT >= 8) {
Resources resources = getResources();
if (searchable.getVoiceLanguageModeId() != 0) {
languageModel = resources.getString(searchable.getVoiceLanguageModeId());
}
if (searchable.getVoicePromptTextId() != 0) {
prompt = resources.getString(searchable.getVoicePromptTextId());
}
if (searchable.getVoiceLanguageId() != 0) {
language = resources.getString(searchable.getVoiceLanguageId());
}
if (searchable.getVoiceMaxResults() != 0) {
maxResults = searchable.getVoiceMaxResults();
}
}
voiceIntent.putExtra("android.speech.extra.LANGUAGE_MODEL", languageModel);
voiceIntent.putExtra("android.speech.extra.PROMPT", prompt);
voiceIntent.putExtra("android.speech.extra.LANGUAGE", language);
voiceIntent.putExtra("android.speech.extra.MAX_RESULTS", maxResults);
voiceIntent.putExtra("calling_package", searchActivity == null ? null : searchActivity.flattenToShortString());
voiceIntent.putExtra("android.speech.extra.RESULTS_PENDINGINTENT", pending);
voiceIntent.putExtra("android.speech.extra.RESULTS_PENDINGINTENT_BUNDLE", queryExtras);
return voiceIntent;
}
private Intent createIntentFromSuggestion(Cursor c, int actionKey, String actionMsg) {
try {
String action = SuggestionsAdapter.getColumnString(c, "suggest_intent_action");
if (action == null && VERSION.SDK_INT >= 8) {
action = this.mSearchable.getSuggestIntentAction();
}
if (action == null) {
action = "android.intent.action.SEARCH";
}
String data = SuggestionsAdapter.getColumnString(c, "suggest_intent_data");
if (IS_AT_LEAST_FROYO && data == null) {
data = this.mSearchable.getSuggestIntentData();
}
if (data != null) {
String id = SuggestionsAdapter.getColumnString(c, "suggest_intent_data_id");
if (id != null) {
data = data + "/" + Uri.encode(id);
}
}
return createIntent(action, data == null ? null : Uri.parse(data), SuggestionsAdapter.getColumnString(c, "suggest_intent_extra_data"), SuggestionsAdapter.getColumnString(c, "suggest_intent_query"), actionKey, actionMsg);
} catch (RuntimeException e) {
int rowNum;
try {
rowNum = c.getPosition();
} catch (RuntimeException e2) {
rowNum = -1;
}
Log.w(LOG_TAG, "Search suggestions cursor at row " + rowNum + " returned exception.", e);
return null;
}
}
private void forceSuggestionQuery() {
HIDDEN_METHOD_INVOKER.doBeforeTextChanged(this.mSearchSrcTextView);
HIDDEN_METHOD_INVOKER.doAfterTextChanged(this.mSearchSrcTextView);
}
static boolean isLandscapeMode(Context context) {
return context.getResources().getConfiguration().orientation == 2;
}
}