Index: chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java |
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java |
deleted file mode 100644 |
index 65f204b1c01fcf97622292a33633b1f1ef441cc8..0000000000000000000000000000000000000000 |
--- a/chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java |
+++ /dev/null |
@@ -1,2422 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-package org.chromium.chrome.browser.omnibox; |
- |
-import static org.chromium.chrome.browser.toolbar.ToolbarPhone.URL_FOCUS_CHANGE_ANIMATION_DURATION_MS; |
- |
-import android.animation.Animator; |
-import android.animation.AnimatorListenerAdapter; |
-import android.animation.AnimatorSet; |
-import android.animation.ObjectAnimator; |
-import android.annotation.SuppressLint; |
-import android.app.Activity; |
-import android.content.ClipData; |
-import android.content.ClipboardManager; |
-import android.content.ContentResolver; |
-import android.content.Context; |
-import android.content.Intent; |
-import android.content.res.ColorStateList; |
-import android.graphics.Color; |
-import android.graphics.PorterDuff; |
-import android.graphics.Rect; |
-import android.graphics.drawable.ColorDrawable; |
-import android.graphics.drawable.Drawable; |
-import android.net.Uri; |
-import android.os.Parcelable; |
-import android.os.SystemClock; |
-import android.provider.Settings; |
-import android.speech.RecognizerIntent; |
-import android.text.Editable; |
-import android.text.InputType; |
-import android.text.Selection; |
-import android.text.TextUtils; |
-import android.text.TextWatcher; |
-import android.util.AttributeSet; |
-import android.util.Log; |
-import android.util.Pair; |
-import android.util.SparseArray; |
-import android.view.ActionMode; |
-import android.view.KeyEvent; |
-import android.view.LayoutInflater; |
-import android.view.Menu; |
-import android.view.MenuItem; |
-import android.view.MotionEvent; |
-import android.view.View; |
-import android.view.View.OnClickListener; |
-import android.view.ViewGroup; |
-import android.view.ViewStub; |
-import android.view.inputmethod.BaseInputConnection; |
-import android.widget.FrameLayout; |
-import android.widget.ImageButton; |
-import android.widget.ImageView; |
-import android.widget.ListView; |
- |
-import org.chromium.base.ApiCompatibilityUtils; |
-import org.chromium.base.CollectionUtil; |
-import org.chromium.base.CommandLine; |
-import org.chromium.base.VisibleForTesting; |
-import org.chromium.base.metrics.RecordHistogram; |
-import org.chromium.base.metrics.RecordUserAction; |
-import org.chromium.chrome.R; |
-import org.chromium.chrome.browser.ChromeSwitches; |
-import org.chromium.chrome.browser.ContextualMenuBar; |
-import org.chromium.chrome.browser.ContextualMenuBar.ActionBarDelegate; |
-import org.chromium.chrome.browser.CustomSelectionActionModeCallback; |
-import org.chromium.chrome.browser.Tab; |
-import org.chromium.chrome.browser.WebsiteSettingsPopup; |
-import org.chromium.chrome.browser.WindowDelegate; |
-import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper; |
-import org.chromium.chrome.browser.document.BrandColorUtils; |
-import org.chromium.chrome.browser.dom_distiller.DomDistillerServiceFactory; |
-import org.chromium.chrome.browser.dom_distiller.DomDistillerTabUtils; |
-import org.chromium.chrome.browser.ntp.NativePageFactory; |
-import org.chromium.chrome.browser.ntp.NewTabPage; |
-import org.chromium.chrome.browser.ntp.NewTabPage.FakeboxDelegate; |
-import org.chromium.chrome.browser.ntp.NewTabPageUma; |
-import org.chromium.chrome.browser.omnibox.AutocompleteController.OnSuggestionsReceivedListener; |
-import org.chromium.chrome.browser.omnibox.OmniboxResultsAdapter.OmniboxResultItem; |
-import org.chromium.chrome.browser.omnibox.OmniboxResultsAdapter.OmniboxSuggestionDelegate; |
-import org.chromium.chrome.browser.omnibox.OmniboxSuggestion.Type; |
-import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider.VoiceResult; |
-import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; |
-import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager; |
-import org.chromium.chrome.browser.profiles.Profile; |
-import org.chromium.chrome.browser.search_engines.TemplateUrlService; |
-import org.chromium.chrome.browser.ssl.ConnectionSecurityLevel; |
-import org.chromium.chrome.browser.tab.BackgroundContentViewHelper; |
-import org.chromium.chrome.browser.tab.ChromeTab; |
-import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; |
-import org.chromium.chrome.browser.toolbar.ToolbarPhone; |
-import org.chromium.chrome.browser.util.FeatureUtilities; |
-import org.chromium.chrome.browser.util.KeyNavigationUtil; |
-import org.chromium.chrome.browser.util.ViewUtils; |
-import org.chromium.chrome.browser.widget.TintedImageButton; |
-import org.chromium.components.dom_distiller.core.DomDistillerService; |
-import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
-import org.chromium.content.browser.ContentViewCore; |
-import org.chromium.content.browser.accessibility.BrowserAccessibilityManager; |
-import org.chromium.content_public.browser.LoadUrlParams; |
-import org.chromium.content_public.browser.WebContents; |
-import org.chromium.ui.UiUtils; |
-import org.chromium.ui.base.DeviceFormFactor; |
-import org.chromium.ui.base.PageTransition; |
-import org.chromium.ui.base.WindowAndroid; |
-import org.chromium.ui.interpolators.BakedBezierInterpolator; |
- |
-import java.util.ArrayList; |
-import java.util.HashSet; |
-import java.util.List; |
- |
-/** |
- * This class represents the location bar where the user types in URLs and |
- * search terms. |
- */ |
-public class LocationBarLayout extends FrameLayout implements OnClickListener, |
- OnSuggestionsReceivedListener, LocationBar, FakeboxDelegate, |
- WindowAndroid.IntentCallback { |
- |
- // Delay triggering the omnibox results upon key press to allow the location bar to repaint |
- // with the new characters. |
- private static final long OMNIBOX_SUGGESTION_START_DELAY_MS = 30; |
- |
- private static final int OMNIBOX_CONTAINER_BACKGROUND_FADE_MS = 250; |
- |
- // The minimum confidence threshold that will result in navigating directly to a voice search |
- // response (as opposed to treating it like a typed string in the Omnibox). |
- private static final float VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD = 0.9f; |
- |
- private static final int CONTENT_OVERLAY_COLOR = Color.argb(166, 0, 0, 0); |
- private static final int OMNIBOX_RESULTS_BG_COLOR = Color.rgb(245, 245, 246); |
- private static final int OMNIBOX_INCOGNITO_RESULTS_BG_COLOR = Color.rgb(50, 50, 50); |
- |
- /** |
- * URI schemes that ContentView can handle. |
- * |
- * Copied from UrlUtilities.java. UrlUtilities uses a URI to check for schemes, which |
- * is more strict than Uri and causes the path stripping to fail. |
- * |
- * The following additions have been made: "chrome", "ftp". |
- */ |
- private static final HashSet<String> ACCEPTED_SCHEMES = CollectionUtil.newHashSet( |
- "about", "data", "file", "ftp", "http", "https", "inline", "javascript", "chrome"); |
- private static final HashSet<String> UNSUPPORTED_SCHEMES_TO_SPLIT = |
- CollectionUtil.newHashSet("file", "javascript", "data"); |
- |
- protected ImageView mNavigationButton; |
- protected ImageButton mSecurityButton; |
- protected TintedImageButton mDeleteButton; |
- protected TintedImageButton mMicButton; |
- protected UrlBar mUrlBar; |
- protected UrlContainer mUrlContainer; |
- private ContextualMenuBar mContextualMenuBar = null; |
- |
- private AutocompleteController mAutocomplete; |
- |
- private ToolbarDataProvider mToolbarDataProvider; |
- private UrlFocusChangeListener mUrlFocusChangeListener; |
- |
- private boolean mNativeInitialized; |
- |
- private final List<Runnable> mDeferredNativeRunnables = new ArrayList<Runnable>(); |
- |
- // The type of the navigation button currently showing. |
- private NavigationButtonType mNavigationButtonType; |
- |
- // The type of the security icon currently active. |
- private int mSecurityIconType; |
- |
- private final OmniboxResultsAdapter mSuggestionListAdapter; |
- private OmniboxSuggestionsList mSuggestionList; |
- |
- private final List<OmniboxResultItem> mSuggestionItems; |
- |
- /** |
- * The text shown in the URL bar (user text + inline autocomplete) after the most recent set of |
- * omnibox suggestions was received. When the user presses enter in the omnibox, this value is |
- * compared to the URL bar text to determine whether the first suggestion is still valid. |
- */ |
- private String mUrlTextAfterSuggestionsReceived; |
- |
- // Set to true when the URL bar text is modified programmatically. Initially set |
- // to true until the old state has been loaded. |
- private boolean mIgnoreURLBarModification = true; |
- private boolean mIgnoreOmniboxItemSelection = true; |
- |
- private boolean mLastUrlEditWasDelete = false; |
- |
- // True if we are showing the search query instead of the url. |
- private boolean mQueryInTheOmnibox = false; |
- |
- private String mOriginalUrl = ""; |
- |
- private WindowAndroid mWindowAndroid; |
- private WindowDelegate mWindowDelegate; |
- |
- private Runnable mRequestSuggestions; |
- |
- private ViewGroup mOmniboxResultsContainer; |
- private ObjectAnimator mFadeInOmniboxBackgroundAnimator; |
- private ObjectAnimator mFadeOutOmniboxBackgroundAnimator; |
- private Animator mOmniboxBackgroundAnimator; |
- |
- private boolean mSuggestionsShown; |
- private boolean mUrlHasFocus; |
- private boolean mUrlFocusedFromFakebox; |
- private boolean mHasRecordedUrlFocusSource; |
- |
- // Set to true when the user has started typing new input in the omnibox, set to false |
- // when the omnibox loses focus or becomes empty. |
- private boolean mHasStartedNewOmniboxEditSession; |
- // The timestamp (using SystemClock.elapsedRealtime()) at the point when the user started |
- // modifying the omnibox with new input. |
- private long mNewOmniboxEditSessionTimestamp = -1; |
- |
- private boolean mSecurityButtonShown; |
- |
- private AnimatorSet mLocationBarIconActiveAnimator; |
- private AnimatorSet mSecurityButtonShowAnimator; |
- private AnimatorSet mNavigationIconShowAnimator; |
- |
- private TextWatcher mTextWatcher; |
- |
- private OmniboxPrerender mOmniboxPrerender; |
- |
- private View mFocusedTabView; |
- private int mFocusedTabImportantForAccessibilityState; |
- private BrowserAccessibilityManager mFocusedTabAccessibilityManager; |
- |
- // True if we are showing original url for preview page. This is will be true when there is a |
- // background page loaded in background content view. |
- private boolean mShowingOriginalUrlForPreview; |
- |
- private boolean mSuggestionModalShown; |
- private boolean mUseDarkColors; |
- |
- // True if the user has just selected a suggestion from the suggestion list. This suppresses |
- // the recording of the dismissal of the suggestion list. (The list is only considered to have |
- // been dismissed if the user didn't choose one of the suggestions shown.) This signal is used |
- // instead of a parameter to hideSuggestions because that method is often called from multiple |
- // code paths in a not necessarily obvious or even deterministic order. |
- private boolean mSuggestionSelectionInProgress; |
- |
- private CustomSelectionActionModeCallback mDefaultActionModeCallbackForTextEdit; |
- |
- private Runnable mShowSuggestions; |
- |
- /** |
- * Listener for receiving the messages related with interacting with the omnibox during startup. |
- */ |
- public interface OmniboxLivenessListener { |
- /** |
- * Called after the first draw when the omnibox can receive touch events. |
- */ |
- void onOmniboxInteractive(); |
- |
- /** |
- * Called when the native libraries are loaded and listeners with native components |
- * have been initialized. |
- */ |
- void onOmniboxFullyFunctional(); |
- |
- /** |
- * Called when the omnibox is focused. |
- */ |
- void onOmniboxFocused(); |
- } |
- |
- /** |
- * Class to handle text changes in the URL bar, ensuring that the appropriate |
- * buttons are displayed as the text changes, and requesting suggestions. |
- */ |
- private final class UrlBarTextWatcher implements TextWatcher { |
- @Override |
- public void afterTextChanged(final Editable editableText) { |
- updateDeleteButtonVisibility(); |
- updateNavigationButton(); |
- |
- if (mIgnoreURLBarModification) return; |
- |
- if (!mHasStartedNewOmniboxEditSession && mNativeInitialized) { |
- RecordUserAction.record("MobileFirstEditInOmnibox"); |
- mAutocomplete.resetSession(); |
- mHasStartedNewOmniboxEditSession = true; |
- mNewOmniboxEditSessionTimestamp = SystemClock.elapsedRealtime(); |
- } |
- |
- if (!isInTouchMode() && mSuggestionList != null) { |
- mSuggestionList.setSelection(0); |
- } |
- |
- stopAutocomplete(false); |
- if (TextUtils.isEmpty(mUrlBar.getTextWithoutAutocomplete())) { |
- hideSuggestions(); |
- startZeroSuggest(); |
- } else { |
- assert mRequestSuggestions == null : "Multiple omnibox requests in flight."; |
- mRequestSuggestions = new Runnable() { |
- @Override |
- public void run() { |
- String textWithoutAutocomplete = mUrlBar.getTextWithoutAutocomplete(); |
- |
- boolean preventAutocomplete = !shouldAutocomplete() |
- || (editableText != null && Selection.getSelectionEnd(editableText) |
- != editableText.length()); |
- mRequestSuggestions = null; |
- if (getCurrentTab() == null) return; |
- mAutocomplete.start( |
- getCurrentTab().getProfile(), |
- getCurrentTab().getUrl(), |
- textWithoutAutocomplete, preventAutocomplete); |
- } |
- }; |
- if (mNativeInitialized) { |
- postDelayed(mRequestSuggestions, OMNIBOX_SUGGESTION_START_DELAY_MS); |
- } else { |
- mDeferredNativeRunnables.add(mRequestSuggestions); |
- } |
- } |
- |
- // Occasionally, was seeing the selection in the URL not being cleared during |
- // very rapid editing. This is here to hopefully force a selection reset during |
- // deletes. |
- if (mLastUrlEditWasDelete) mUrlBar.setSelection(mUrlBar.getSelectionStart()); |
- } |
- |
- @Override |
- public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
- cancelPendingAutocompleteStart(); |
- } |
- |
- @Override |
- public void onTextChanged(CharSequence s, int start, int before, int count) { |
- // We need to determine whether the text change was triggered by a delete (so we |
- // don't autocomplete of the entered text in that case). With soft-keyboard, there |
- // is no way to know that the delete button was pressed, so we track text removal |
- // changes. |
- mLastUrlEditWasDelete = (count == 0); |
- } |
- } |
- |
- /** |
- * Class to handle input from a hardware keyboard when the focus is on the URL bar. In |
- * particular, handle navigating the suggestions list from the keyboard. |
- */ |
- private final class UrlBarKeyListener implements OnKeyListener { |
- @Override |
- public boolean onKey(View v, int keyCode, KeyEvent event) { |
- if (KeyNavigationUtil.isGoDown(event) |
- && mSuggestionList != null |
- && mSuggestionList.isShown()) { |
- int suggestionCount = mSuggestionListAdapter.getCount(); |
- if (mSuggestionList.getSelectedItemPosition() < suggestionCount - 1) { |
- if (suggestionCount > 0) mIgnoreOmniboxItemSelection = false; |
- } else { |
- // Do not pass down events when the last item is already selected as it will |
- // dismiss the suggestion list. |
- return true; |
- } |
- |
- if (mSuggestionList.getSelectedItemPosition() |
- == ListView.INVALID_POSITION) { |
- // When clearing the selection after a text change, state is not reset |
- // correctly so hitting down again will cause it to start from the previous |
- // selection point. We still have to send the key down event to let the list |
- // view items take focus, but then we select the first item explicitly. |
- boolean result = mSuggestionList.onKeyDown(keyCode, event); |
- mSuggestionList.setSelection(0); |
- return result; |
- } else { |
- return mSuggestionList.onKeyDown(keyCode, event); |
- } |
- } else if (KeyNavigationUtil.isGoUp(event) |
- && mSuggestionList != null |
- && mSuggestionList.isShown()) { |
- if (mSuggestionList.getSelectedItemPosition() != 0 |
- && mSuggestionListAdapter.getCount() > 0) { |
- mIgnoreOmniboxItemSelection = false; |
- } |
- return mSuggestionList.onKeyDown(keyCode, event); |
- } else if (KeyNavigationUtil.isGoRight(event) |
- && mSuggestionList != null |
- && mSuggestionList.isShown() |
- && mSuggestionList.getSelectedItemPosition() |
- != ListView.INVALID_POSITION) { |
- OmniboxResultItem selectedItem = |
- (OmniboxResultItem) mSuggestionListAdapter.getItem( |
- mSuggestionList.getSelectedItemPosition()); |
- // Set the UrlBar text to empty, so that it will trigger a text change when we |
- // set the text to the suggestion again. |
- setUrlBarText(null, null, ""); |
- mUrlBar.setText(selectedItem.getSuggestion().getFillIntoEdit()); |
- mSuggestionList.setSelection(0); |
- mUrlBar.setSelection(mUrlBar.getText().length()); |
- return true; |
- } else if (KeyNavigationUtil.isEnter(event) |
- && LocationBarLayout.this.getVisibility() == VISIBLE) { |
- UiUtils.hideKeyboard(mUrlBar); |
- mSuggestionSelectionInProgress = true; |
- final String urlText = mUrlBar.getQueryText(); |
- if (mNativeInitialized) { |
- findMatchAndLoadUrl(urlText); |
- } else { |
- mDeferredNativeRunnables.add(new Runnable() { |
- @Override |
- public void run() { |
- findMatchAndLoadUrl(urlText); |
- } |
- }); |
- } |
- return true; |
- } |
- |
- return false; |
- } |
- |
- private void findMatchAndLoadUrl(String urlText) { |
- int suggestionMatchPosition; |
- OmniboxSuggestion suggestionMatch; |
- |
- if (mSuggestionList != null |
- && mSuggestionList.isShown() |
- && mSuggestionList.getSelectedItemPosition() |
- != ListView.INVALID_POSITION) { |
- // Bluetooth keyboard case: the user highlighted a suggestion with the arrow |
- // keys, then pressed enter. |
- suggestionMatchPosition = mSuggestionList.getSelectedItemPosition(); |
- OmniboxResultItem selectedItem = |
- (OmniboxResultItem) mSuggestionListAdapter.getItem(suggestionMatchPosition); |
- suggestionMatch = selectedItem.getSuggestion(); |
- } else if (!mSuggestionItems.isEmpty() |
- && urlText.equals(mUrlTextAfterSuggestionsReceived)) { |
- // Common case: the user typed something, received suggestions, then pressed enter. |
- suggestionMatch = mSuggestionItems.get(0).getSuggestion(); |
- suggestionMatchPosition = 0; |
- } else { |
- // Less common case: there are no valid omnibox suggestions. This can happen if the |
- // user tapped the URL bar to dismiss the suggestions, then pressed enter. This can |
- // also happen if the user presses enter before any suggestions have been received |
- // from the autocomplete controller. |
- suggestionMatch = mAutocomplete.classify(urlText); |
- suggestionMatchPosition = 0; |
- |
- // If urlText couldn't be classified, bail. |
- if (suggestionMatch == null) return; |
- } |
- |
- String suggestionMatchUrl = updateSuggestionUrlIfNeeded(suggestionMatch, |
- suggestionMatchPosition); |
- |
- // It's important to use the page transition from the suggestion or we might end |
- // up saving generated URLs as typed URLs, which would then pollute the subsequent |
- // omnibox results. |
- loadUrlFromOmniboxMatch(suggestionMatchUrl, suggestionMatch.getTransition(), |
- suggestionMatchPosition, suggestionMatch.getType()); |
- } |
- } |
- |
- /** |
- * Specifies the types of buttons shown to signify different types of navigation elements. |
- */ |
- protected enum NavigationButtonType { |
- PAGE, |
- MAGNIFIER, |
- EMPTY, |
- } |
- |
- /** |
- * @param outRect Populated with a {@link Rect} that represents the {@link Tab} specific content |
- * of this {@link LocationBar}. |
- */ |
- public void getContentRect(Rect outRect) { |
- outRect.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), |
- getHeight() - getPaddingBottom()); |
- } |
- |
- /** |
- * A widget for showing a list of omnibox suggestions. |
- */ |
- @VisibleForTesting |
- public class OmniboxSuggestionsList extends ListView { |
- private final int mSuggestionHeight; |
- private final int mSuggestionAnswerHeight; |
- private final View mAnchorView; |
- |
- private final int[] mTempPosition = new int[2]; |
- private final Rect mTempRect = new Rect(); |
- |
- private final int mBackgroundVerticalPadding; |
- |
- private float mMaxRequiredWidth; |
- private float mMaxMatchContentsWidth; |
- |
- /** |
- * Constructs a new list designed for containing omnibox suggestions. |
- * @param context Context used for contained views. |
- */ |
- public OmniboxSuggestionsList(Context context) { |
- super(context, null, android.R.attr.dropDownListViewStyle); |
- setDivider(null); |
- setFocusable(true); |
- setFocusableInTouchMode(true); |
- |
- mSuggestionHeight = context.getResources().getDimensionPixelOffset( |
- R.dimen.omnibox_suggestion_height); |
- mSuggestionAnswerHeight = context.getResources().getDimensionPixelOffset( |
- R.dimen.omnibox_suggestion_answer_height); |
- |
- int paddingTop = context.getResources().getDimensionPixelOffset( |
- R.dimen.omnibox_suggestion_list_padding_top); |
- int paddingBottom = context.getResources().getDimensionPixelOffset( |
- R.dimen.omnibox_suggestion_list_padding_bottom); |
- ApiCompatibilityUtils.setPaddingRelative(this, 0, paddingTop, 0, paddingBottom); |
- |
- Drawable background = getSuggestionPopupBackground(); |
- setBackground(background); |
- background.getPadding(mTempRect); |
- |
- mBackgroundVerticalPadding = |
- mTempRect.top + mTempRect.bottom + getPaddingTop() + getPaddingBottom(); |
- |
- mAnchorView = LocationBarLayout.this.getRootView().findViewById(R.id.toolbar); |
- } |
- |
- private void show() { |
- updateLayoutParams(); |
- if (getVisibility() != VISIBLE) { |
- mIgnoreOmniboxItemSelection = true; // Reset to default value. |
- setVisibility(VISIBLE); |
- if (getSelectedItemPosition() != 0) setSelection(0); |
- } |
- updateSuggestionsLayoutDirection(mUrlBar.getUrlDirection()); |
- } |
- |
- /** |
- * Invalidates all of the suggestion views in the list. Only applicable when this |
- * is visible. |
- */ |
- public void invalidateSuggestionViews() { |
- if (!isShown()) return; |
- ListView suggestionsList = mSuggestionList; |
- for (int i = 0; i < suggestionsList.getChildCount(); i++) { |
- if (suggestionsList.getChildAt(i) instanceof SuggestionView) { |
- suggestionsList.getChildAt(i).postInvalidateOnAnimation(); |
- } |
- } |
- } |
- |
- /** |
- * Updates the maximum widths required to render the suggestions. |
- * This is needed for infinite suggestions where we try to vertically align the leading |
- * ellipsis. |
- */ |
- public void resetMaxTextWidths() { |
- mMaxRequiredWidth = 0; |
- mMaxMatchContentsWidth = 0; |
- } |
- |
- /** |
- * Updates the max text width values for the suggestions. |
- * @param requiredWidth a new required width. |
- * @param matchContentsWidth a new match contents width. |
- */ |
- public void updateMaxTextWidths(float requiredWidth, float matchContentsWidth) { |
- mMaxRequiredWidth = Math.max(mMaxRequiredWidth, requiredWidth); |
- mMaxMatchContentsWidth = Math.max(mMaxMatchContentsWidth, matchContentsWidth); |
- } |
- |
- /** |
- * @return max required width for the suggestions. |
- */ |
- public float getMaxRequiredWidth() { |
- return mMaxRequiredWidth; |
- } |
- |
- /** |
- * @return max match contents width for the suggestions. |
- */ |
- public float getMaxMatchContentsWidth() { |
- return mMaxMatchContentsWidth; |
- } |
- |
- private void updateLayoutParams() { |
- boolean updateLayout = false; |
- FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams(); |
- if (layoutParams == null) { |
- layoutParams = new FrameLayout.LayoutParams(0, 0); |
- setLayoutParams(layoutParams); |
- } |
- |
- // Compare the relative positions of the anchor view to the list parent view to |
- // determine the offset to apply to the suggestions list. By using layout positioning, |
- // this avoids issues where getLocationInWindow can be inaccurate on certain devices. |
- View contentView = |
- LocationBarLayout.this.getRootView().findViewById(android.R.id.content); |
- ViewUtils.getRelativeLayoutPosition(contentView, mAnchorView, mTempPosition); |
- int anchorX = mTempPosition[0]; |
- int anchorY = mTempPosition[1]; |
- |
- ViewUtils.getRelativeLayoutPosition(contentView, (View) getParent(), mTempPosition); |
- int parentY = mTempPosition[1]; |
- |
- int anchorBottomRelativeToContent = anchorY + mAnchorView.getMeasuredHeight(); |
- int desiredTopMargin = anchorBottomRelativeToContent - parentY; |
- if (layoutParams.topMargin != desiredTopMargin) { |
- layoutParams.topMargin = desiredTopMargin; |
- updateLayout = true; |
- } |
- |
- int contentLeft = contentView.getLeft(); |
- int anchorLeftRelativeToContent = anchorX - contentLeft; |
- if (layoutParams.leftMargin != anchorLeftRelativeToContent) { |
- layoutParams.leftMargin = anchorLeftRelativeToContent; |
- updateLayout = true; |
- } |
- |
- getWindowDelegate().getWindowVisibleDisplayFrame(mTempRect); |
- int decorHeight = getWindowDelegate().getDecorViewHeight(); |
- int availableViewportHeight = Math.min(mTempRect.height(), decorHeight); |
- int availableListHeight = availableViewportHeight - anchorBottomRelativeToContent; |
- int desiredHeight = Math.min(availableListHeight, getIdealHeight()); |
- if (layoutParams.height != desiredHeight) { |
- layoutParams.height = desiredHeight; |
- updateLayout = true; |
- } |
- |
- int desiredWidth = getDesiredWidth(); |
- if (layoutParams.width != desiredWidth) { |
- layoutParams.width = desiredWidth; |
- updateLayout = true; |
- } |
- |
- if (updateLayout) requestLayout(); |
- } |
- |
- private int getIdealHeight() { |
- int idealListSize = mBackgroundVerticalPadding; |
- for (int i = 0; i < mSuggestionItems.size(); i++) { |
- OmniboxResultItem item = mSuggestionItems.get(i); |
- if (!TextUtils.isEmpty(item.getSuggestion().getAnswerContents())) { |
- idealListSize += mSuggestionAnswerHeight; |
- } else { |
- idealListSize += mSuggestionHeight; |
- } |
- } |
- return idealListSize; |
- } |
- |
- private int getDesiredWidth() { |
- return mAnchorView.getWidth(); |
- } |
- |
- @Override |
- public void onWindowFocusChanged(boolean hasWindowFocus) { |
- super.onWindowFocusChanged(hasWindowFocus); |
- if (!hasWindowFocus && !mSuggestionModalShown) hideSuggestions(); |
- } |
- |
- @Override |
- protected void layoutChildren() { |
- super.layoutChildren(); |
- // In ICS, the selected view is not marked as selected despite calling setSelection(0), |
- // so we bootstrap this after the children have been laid out. |
- if (!isInTouchMode() && getSelectedView() != null) { |
- getSelectedView().setSelected(true); |
- } |
- } |
- } |
- |
- public LocationBarLayout(Context context, AttributeSet attrs) { |
- super(context, attrs); |
- |
- LayoutInflater.from(context).inflate(R.layout.location_bar, this, true); |
- mNavigationButton = (ImageView) findViewById(R.id.navigation_button); |
- assert mNavigationButton != null : "Missing navigation type view."; |
- mNavigationButtonType = DeviceFormFactor.isTablet(context) |
- ? NavigationButtonType.PAGE : NavigationButtonType.EMPTY; |
- |
- mSecurityButton = (ImageButton) findViewById(R.id.security_button); |
- mSecurityIconType = ConnectionSecurityLevel.NONE; |
- |
- mDeleteButton = (TintedImageButton) findViewById(R.id.delete_button); |
- |
- mUrlBar = (UrlBar) findViewById(R.id.url_bar); |
- // The HTC Sense IME will attempt to autocomplete words in the Omnibox when Prediction is |
- // enabled. We want to disable this feature and rely on the Omnibox's implementation. |
- // Their IME does not respect ~TYPE_TEXT_FLAG_AUTO_COMPLETE nor any of the other InputType |
- // options I tried, but setting the filter variation prevents it. Sadly, it also removes |
- // the .com button, but the prediction was buggy as it would autocomplete words even when |
- // typing at the beginning of the omnibox text when other content was present (messing up |
- // what was previously there). See bug: http://b/issue?id=6200071 |
- String defaultIme = Settings.Secure.getString(getContext().getContentResolver(), |
- Settings.Secure.DEFAULT_INPUT_METHOD); |
- if (defaultIme != null && defaultIme.contains("com.htc.android.htcime")) { |
- mUrlBar.setInputType(mUrlBar.getInputType() | InputType.TYPE_TEXT_VARIATION_FILTER); |
- } |
- mUrlBar.setDelegate(this); |
- |
- mUrlContainer = (UrlContainer) findViewById(R.id.url_container); |
- |
- mSuggestionItems = new ArrayList<OmniboxResultItem>(); |
- mSuggestionListAdapter = new OmniboxResultsAdapter(getContext(), this, mSuggestionItems); |
- |
- mMicButton = (TintedImageButton) findViewById(R.id.mic_button); |
- } |
- |
- @Override |
- protected void onFinishInflate() { |
- super.onFinishInflate(); |
- |
- mUrlBar.setCursorVisible(false); |
- mNavigationButton.setVisibility(VISIBLE); |
- mSecurityButton.setVisibility(INVISIBLE); |
- |
- setLayoutTransition(null); |
- |
- AnimatorListenerAdapter iconChangeAnimatorListener = new AnimatorListenerAdapter() { |
- @Override |
- public void onAnimationEnd(Animator animation) { |
- if (animation == mSecurityButtonShowAnimator) { |
- mNavigationButton.setVisibility(INVISIBLE); |
- } else if (animation == mNavigationIconShowAnimator) { |
- mSecurityButton.setVisibility(INVISIBLE); |
- } |
- } |
- |
- @Override |
- public void onAnimationStart(Animator animation) { |
- if (animation == mSecurityButtonShowAnimator) { |
- mSecurityButton.setVisibility(VISIBLE); |
- } else if (animation == mNavigationIconShowAnimator) { |
- mNavigationButton.setVisibility(VISIBLE); |
- } |
- } |
- }; |
- |
- mSecurityButtonShowAnimator = new AnimatorSet(); |
- mSecurityButtonShowAnimator.playTogether( |
- ObjectAnimator.ofFloat(mNavigationButton, ALPHA, 0), |
- ObjectAnimator.ofFloat(mSecurityButton, ALPHA, 1)); |
- mSecurityButtonShowAnimator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); |
- mSecurityButtonShowAnimator.addListener(iconChangeAnimatorListener); |
- |
- mNavigationIconShowAnimator = new AnimatorSet(); |
- mNavigationIconShowAnimator.playTogether( |
- ObjectAnimator.ofFloat(mNavigationButton, ALPHA, 1), |
- ObjectAnimator.ofFloat(mSecurityButton, ALPHA, 0)); |
- mNavigationIconShowAnimator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); |
- mNavigationIconShowAnimator.addListener(iconChangeAnimatorListener); |
- |
- mUrlBar.setOnKeyListener(new UrlBarKeyListener()); |
- |
- mTextWatcher = new UrlBarTextWatcher(); |
- mUrlBar.setLocationBarTextWatcher(mTextWatcher); |
- |
- // mLocationBar's direction is tied to this UrlBar's text direction. Icons inside the |
- // location bar, e.g. lock, refresh, X, should be reversed if UrlBar's text is RTL. |
- mUrlBar.setUrlDirectionListener(new UrlBar.UrlDirectionListener() { |
- @Override |
- public void onUrlDirectionChanged(int layoutDirection) { |
- ApiCompatibilityUtils.setLayoutDirection(LocationBarLayout.this, layoutDirection); |
- updateSuggestionsLayoutDirection(layoutDirection); |
- } |
- }); |
- |
- mUrlBar.setSelectAllOnFocus(true); |
- } |
- |
- @Override |
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
- updateLayoutParams(); |
- super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
- } |
- |
- private void updateSuggestionsLayoutDirection(int layoutDirection) { |
- if (mSuggestionList != null && mSuggestionList.isShown()) { |
- ListView listView = mSuggestionList; |
- ApiCompatibilityUtils.setLayoutDirection(listView, layoutDirection); |
- for (int i = 0; i < listView.getChildCount(); i++) { |
- ApiCompatibilityUtils.setLayoutDirection(listView.getChildAt(i), |
- layoutDirection); |
- } |
- } |
- } |
- |
- @Override |
- public void initializeControls(WindowDelegate windowDelegate, |
- ActionBarDelegate actionBarDelegate, WindowAndroid windowAndroid) { |
- mWindowDelegate = windowDelegate; |
- |
- mContextualMenuBar = new ContextualMenuBar(getContext(), actionBarDelegate); |
- mContextualMenuBar.setCustomSelectionActionModeCallback( |
- new CustomSelectionActionModeCallback() { |
- @Override |
- public boolean onCreateActionMode(ActionMode mode, Menu menu) { |
- boolean retVal = super.onCreateActionMode(mode, menu); |
- mode.getMenuInflater().inflate(R.menu.textselectionmenu, menu); |
- return retVal; |
- } |
- |
- @Override |
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) { |
- if (item.getItemId() == R.id.copy_url) { |
- ClipboardManager clipboard = |
- (ClipboardManager) getContext().getSystemService( |
- Context.CLIPBOARD_SERVICE); |
- ClipData clip = ClipData.newPlainText("url", mOriginalUrl); |
- clipboard.setPrimaryClip(clip); |
- mode.finish(); |
- return true; |
- } else { |
- return super.onActionItemClicked(mode, item); |
- } |
- } |
- }); |
- |
- mWindowAndroid = windowAndroid; |
- mMicButton.setOnClickListener(this); |
- } |
- |
- /** |
- * @return The WindowDelegate for the LocationBar. This should be used for all Window related |
- * state queries. |
- */ |
- protected WindowDelegate getWindowDelegate() { |
- return mWindowDelegate; |
- } |
- |
- /** |
- * Handles native dependent initialization for this class. |
- */ |
- @Override |
- public void onNativeLibraryReady() { |
- mNativeInitialized = true; |
- |
- mSecurityButton.setOnClickListener(this); |
- mNavigationButton.setOnClickListener(this); |
- updateMicButtonState(); |
- mDeleteButton.setOnClickListener(this); |
- |
- mAutocomplete = new AutocompleteController(this); |
- |
- mOmniboxPrerender = new OmniboxPrerender(); |
- |
- for (Runnable deferredRunnable : mDeferredNativeRunnables) { |
- post(deferredRunnable); |
- } |
- mDeferredNativeRunnables.clear(); |
- |
- mUrlBar.onOmniboxFullyFunctional(); |
- |
- updateCustomSelectionActionModeCallback(); |
- updateVisualsForState(); |
- } |
- |
- /** |
- * @return Whether or not to animate icon changes. |
- */ |
- protected boolean shouldAnimateIconChanges() { |
- return mUrlHasFocus; |
- } |
- |
- /** |
- * Sets the autocomplete controller for the location bar. |
- * |
- * @param controller The controller that will handle autocomplete/omnibox suggestions. |
- * @note Only used for testing. |
- */ |
- @VisibleForTesting |
- public void setAutocompleteController(AutocompleteController controller) { |
- mAutocomplete = controller; |
- } |
- |
- /** |
- * Updates the profile used for generating autocomplete suggestions. |
- * @param profile The profile to be used. |
- */ |
- @Override |
- public void setAutocompleteProfile(Profile profile) { |
- // This will only be called once at least one tab exists, and the tab model is told to |
- // update its state. During Chrome initialization the tab model update happens after the |
- // call to onNativeLibraryReady, so this assert will not fire. |
- assert mNativeInitialized : |
- "Setting Autocomplete Profile before native side initialized"; |
- mAutocomplete.setProfile(profile); |
- mOmniboxPrerender.initializeForProfile(profile); |
- } |
- |
- private void changeLocationBarIcon(boolean showSecurityButton) { |
- if (mLocationBarIconActiveAnimator != null && mLocationBarIconActiveAnimator.isRunning()) { |
- mLocationBarIconActiveAnimator.cancel(); |
- } |
- View viewToBeShown = showSecurityButton ? mSecurityButton : mNavigationButton; |
- if (viewToBeShown.getVisibility() == VISIBLE && viewToBeShown.getAlpha() == 1) { |
- return; |
- } |
- if (showSecurityButton) { |
- mLocationBarIconActiveAnimator = mSecurityButtonShowAnimator; |
- } else { |
- mLocationBarIconActiveAnimator = mNavigationIconShowAnimator; |
- } |
- if (shouldAnimateIconChanges()) { |
- mLocationBarIconActiveAnimator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); |
- } else { |
- mLocationBarIconActiveAnimator.setDuration(0); |
- } |
- mLocationBarIconActiveAnimator.start(); |
- } |
- |
- @Override |
- public void onUrlPreFocusChanged(boolean gainFocus) { |
- if (mToolbarDataProvider == null || mToolbarDataProvider.getTab() == null) return; |
- |
- if (!mQueryInTheOmnibox |
- && FeatureUtilities.isDocumentMode(getContext()) |
- && !TextUtils.isEmpty(mUrlBar.getText())) { |
- mUrlBar.setUrl(mToolbarDataProvider.getTab().getUrl(), null); |
- } |
- } |
- |
- @Override |
- public void setUrlBarFocus(boolean shouldBeFocused) { |
- if (shouldBeFocused) { |
- mUrlBar.requestFocus(); |
- } else { |
- mUrlBar.clearFocus(); |
- } |
- } |
- |
- @Override |
- public long getFirstUrlBarFocusTime() { |
- return mUrlBar.getFirstFocusTime(); |
- } |
- |
- /** |
- * @return Whether the URL focus change is taking place, e.g. a focus animation is running on |
- * a phone device. |
- */ |
- protected boolean isUrlFocusChangeInProgress() { |
- return false; |
- } |
- |
- /** |
- * Triggered when the URL input field has gained or lost focus. |
- * @param hasFocus Whether the URL field has gained focus. |
- */ |
- public void onUrlFocusChange(boolean hasFocus) { |
- mUrlHasFocus = hasFocus; |
- updateFocusSource(hasFocus); |
- updateDeleteButtonVisibility(); |
- Tab currentTab = getCurrentTab(); |
- if (hasFocus) { |
- mUrlBar.deEmphasizeUrl(); |
- } else { |
- hideSuggestions(); |
- |
- // Focus change caused by a close-tab may result in an invalid current tab. |
- if (currentTab != null) { |
- setUrlToPageUrl(); |
- emphasizeUrl(); |
- } |
- } |
- |
- if (getToolbarDataProvider().isUsingBrandColor()) { |
- updateVisualsForState(); |
- if (mUrlHasFocus) mUrlBar.selectAll(); |
- } |
- |
- if (mUrlFocusChangeListener != null) mUrlFocusChangeListener.onUrlFocusChange(hasFocus); |
- changeLocationBarIcon( |
- (!DeviceFormFactor.isTablet(getContext()) || !hasFocus) && isSecurityButtonShown()); |
- mUrlBar.setCursorVisible(hasFocus); |
- if (mQueryInTheOmnibox) mUrlBar.setSelection(mUrlBar.getSelectionEnd()); |
- |
- updateOmniboxResultsContainer(); |
- if (hasFocus) updateOmniboxResultsContainerBackground(true); |
- |
- if (hasFocus && currentTab != null && !currentTab.isIncognito()) { |
- if (mNativeInitialized |
- && TemplateUrlService.getInstance().isDefaultSearchEngineGoogle()) { |
- GeolocationHeader.primeLocationForGeoHeader(getContext()); |
- } else { |
- mDeferredNativeRunnables.add(new Runnable() { |
- @Override |
- public void run() { |
- if (TemplateUrlService.getInstance().isDefaultSearchEngineGoogle()) { |
- GeolocationHeader.primeLocationForGeoHeader(getContext()); |
- } |
- } |
- }); |
- } |
- } |
- |
- if (mNativeInitialized) { |
- startZeroSuggest(); |
- } else { |
- mDeferredNativeRunnables.add(new Runnable() { |
- @Override |
- public void run() { |
- if (TextUtils.isEmpty(mUrlBar.getQueryText())) { |
- startZeroSuggest(); |
- } |
- } |
- }); |
- } |
- |
- // Add and remove text watcher from the URL bar with focus, so that it's |
- // not called when we modify the displayed information on focus. |
- if (hasFocus) { |
- mUrlBar.addTextChangedListener(mTextWatcher); |
- } else { |
- mUrlBar.removeTextChangedListener(mTextWatcher); |
- } |
- |
- if (!hasFocus) { |
- mHasStartedNewOmniboxEditSession = false; |
- mNewOmniboxEditSessionTimestamp = -1; |
- } |
- } |
- |
- /** |
- * Make a zero suggest request if native is loaded, the URL bar has focus, and the |
- * current tab is not incognito. |
- */ |
- private void startZeroSuggest() { |
- // Reset "edited" state in the omnibox if zero suggest is triggered -- new edits |
- // now count as a new session. |
- mHasStartedNewOmniboxEditSession = false; |
- mNewOmniboxEditSessionTimestamp = -1; |
- Tab currentTab = getCurrentTab(); |
- if (mNativeInitialized |
- && mUrlHasFocus |
- && currentTab != null |
- && !currentTab.isIncognito()) { |
- mAutocomplete.startZeroSuggest(currentTab.getProfile(), mUrlBar.getQueryText(), |
- currentTab.getUrl(), mQueryInTheOmnibox, mUrlFocusedFromFakebox); |
- } |
- } |
- |
- @Override |
- public void setDefaultTextEditActionModeCallback(CustomSelectionActionModeCallback callback) { |
- mDefaultActionModeCallbackForTextEdit = callback; |
- } |
- |
- /** |
- * If query in the omnibox, sets UrlBar's ActionModeCallback to show copy url button. Else, |
- * it is set to the default one. |
- */ |
- private void updateCustomSelectionActionModeCallback() { |
- if (mQueryInTheOmnibox) { |
- mUrlBar.setCustomSelectionActionModeCallback( |
- mContextualMenuBar.getCustomSelectionActionModeCallback()); |
- } else { |
- mUrlBar.setCustomSelectionActionModeCallback(mDefaultActionModeCallbackForTextEdit); |
- } |
- } |
- |
- @Override |
- public void requestUrlFocusFromFakebox(String pastedText) { |
- mUrlFocusedFromFakebox = true; |
- mUrlBar.requestFocus(); |
- |
- if (pastedText != null) { |
- // This must be happen after requestUrlFocus(), which changes the selection. |
- mUrlBar.setUrl(pastedText, null); |
- mUrlBar.setSelection(mUrlBar.getText().length()); |
- } |
- } |
- |
- /** |
- * Sets the toolbar that owns this LocationBar. |
- */ |
- @Override |
- public void setToolbarDataProvider(ToolbarDataProvider toolbarDataProvider) { |
- mToolbarDataProvider = toolbarDataProvider; |
- |
- mUrlBar.setOnFocusChangeListener(new View.OnFocusChangeListener() { |
- @Override |
- public void onFocusChange(View v, final boolean hasFocus) { |
- onUrlFocusChange(hasFocus); |
- } |
- }); |
- } |
- |
- @Override |
- public void setMenuButtonHelper(AppMenuButtonHelper helper) { } |
- |
- @Override |
- public View getMenuAnchor() { |
- return null; |
- } |
- |
- /** |
- * Sets the URL focus change listner that will be notified when the URL gains or loses focus. |
- * @param listener The listener to be registered. |
- */ |
- @Override |
- public void setUrlFocusChangeListener(UrlFocusChangeListener listener) { |
- mUrlFocusChangeListener = listener; |
- } |
- |
- /** |
- * @return The toolbar data provider. |
- */ |
- @VisibleForTesting |
- protected ToolbarDataProvider getToolbarDataProvider() { |
- return mToolbarDataProvider; |
- } |
- |
- private static NavigationButtonType suggestionTypeToNavigationButtonType( |
- OmniboxSuggestion.Type suggestionType) { |
- switch (suggestionType) { |
- case NAVSUGGEST: |
- case HISTORY_URL: |
- case URL_WHAT_YOU_TYPED: |
- case HISTORY_TITLE: |
- case HISTORY_BODY: |
- case HISTORY_KEYWORD: |
- return NavigationButtonType.PAGE; |
- case SEARCH_WHAT_YOU_TYPED: |
- case SEARCH_HISTORY: |
- case SEARCH_SUGGEST: |
- case SEARCH_SUGGEST_ENTITY: |
- case SEARCH_SUGGEST_TAIL: |
- case SEARCH_SUGGEST_PERSONALIZED: |
- case SEARCH_SUGGEST_PROFILE: |
- case VOICE_SUGGEST: |
- case SEARCH_OTHER_ENGINE: |
- case OPEN_HISTORY_PAGE: |
- return NavigationButtonType.MAGNIFIER; |
- default: |
- assert false; |
- return NavigationButtonType.MAGNIFIER; |
- } |
- } |
- |
- // Updates the navigation button based on the URL string |
- private void updateNavigationButton() { |
- boolean isTablet = DeviceFormFactor.isTablet(getContext()); |
- NavigationButtonType type = NavigationButtonType.EMPTY; |
- if (isTablet && !mSuggestionItems.isEmpty()) { |
- // If there are suggestions showing, show the icon for the default suggestion. |
- type = suggestionTypeToNavigationButtonType( |
- mSuggestionItems.get(0).getSuggestion().getType()); |
- } else if (mQueryInTheOmnibox) { |
- type = NavigationButtonType.MAGNIFIER; |
- } else if (isTablet) { |
- type = NavigationButtonType.PAGE; |
- } |
- |
- if (type != mNavigationButtonType) setNavigationButtonType(type); |
- } |
- |
- /** |
- * @return Whether the query is shown in the omnibox instead of the url. |
- */ |
- public boolean showingQueryInTheOmnibox() { |
- return mQueryInTheOmnibox; |
- } |
- |
- /** |
- * @return Whether original url is shown for preview page. |
- */ |
- @Override |
- public boolean showingOriginalUrlForPreview() { |
- return mShowingOriginalUrlForPreview; |
- } |
- |
- private int getSecurityLevel() { |
- if (getCurrentTab() == null) return ConnectionSecurityLevel.NONE; |
- return getCurrentTab().getSecurityLevel(); |
- } |
- |
- /** |
- * Determines the icon that should be displayed for the current security level. |
- * @param securityLevel The security level for which the resource will be returned. |
- * @param usingLightTheme Whether light themed security assets should be used. |
- * @return The resource ID of the icon that should be displayed, 0 if no icon should show. |
- */ |
- public static int getSecurityIconResource(int securityLevel, boolean usingLightTheme) { |
- switch (securityLevel) { |
- case ConnectionSecurityLevel.NONE: |
- return 0; |
- case ConnectionSecurityLevel.SECURITY_WARNING: |
- return R.drawable.omnibox_https_warning; |
- case ConnectionSecurityLevel.SECURITY_ERROR: |
- return R.drawable.omnibox_https_invalid; |
- case ConnectionSecurityLevel.SECURE: |
- case ConnectionSecurityLevel.EV_SECURE: |
- return usingLightTheme |
- ? R.drawable.omnibox_https_valid_light : R.drawable.omnibox_https_valid; |
- default: |
- assert false; |
- } |
- return 0; |
- } |
- |
- /** |
- * Updates the security icon displayed in the LocationBar. |
- */ |
- @Override |
- public void updateSecurityIcon(int securityLevel) { |
- if (showingOriginalUrlForPreview()) { |
- securityLevel = ConnectionSecurityLevel.NONE; |
- } |
- if (mQueryInTheOmnibox) { |
- if (securityLevel == ConnectionSecurityLevel.SECURE |
- || securityLevel == ConnectionSecurityLevel.EV_SECURE) { |
- securityLevel = ConnectionSecurityLevel.NONE; |
- } else if (securityLevel == ConnectionSecurityLevel.SECURITY_WARNING |
- || securityLevel == ConnectionSecurityLevel.SECURITY_ERROR) { |
- setUrlToPageUrl(); |
- } |
- } |
- |
- // ImageView#setImageResource is no-op if given resource is the current one. |
- mSecurityButton.setImageResource( |
- getSecurityIconResource(securityLevel, !shouldEmphasizeHttpsScheme())); |
- |
- if (mSecurityIconType == securityLevel) return; |
- mSecurityIconType = securityLevel; |
- |
- if (securityLevel == ConnectionSecurityLevel.NONE) { |
- updateSecurityButton(false); |
- } else { |
- updateSecurityButton(true); |
- // Since we emphasize the schema of the URL based on the security type, we need to |
- // refresh the emphasis. |
- mUrlBar.deEmphasizeUrl(); |
- } |
- emphasizeUrl(); |
- } |
- |
- private void emphasizeUrl() { |
- if (!mQueryInTheOmnibox) mUrlBar.emphasizeUrl(); |
- } |
- |
- @Override |
- public boolean shouldEmphasizeHttpsScheme() { |
- int securityLevel = getSecurityLevel(); |
- if (securityLevel == ConnectionSecurityLevel.SECURITY_ERROR |
- || securityLevel == ConnectionSecurityLevel.SECURITY_WARNING |
- || securityLevel == ConnectionSecurityLevel.SECURITY_POLICY_WARNING) { |
- return true; |
- } |
- if (getToolbarDataProvider().isUsingBrandColor()) return false; |
- if (getToolbarDataProvider().isIncognito()) return false; |
- return true; |
- } |
- |
- /** |
- * Updates the display of the security button. |
- * @param enabled Whether the security button should be displayed. |
- */ |
- private void updateSecurityButton(boolean enabled) { |
- changeLocationBarIcon(enabled |
- && (!DeviceFormFactor.isTablet(getContext()) || !mUrlHasFocus)); |
- mSecurityButtonShown = enabled; |
- updateLocationBarIconContainerVisibility(); |
- } |
- |
- /** |
- * @return Whether the security button is currently being displayed. |
- */ |
- @VisibleForTesting |
- public boolean isSecurityButtonShown() { |
- return mSecurityButtonShown; |
- } |
- |
- /** |
- * Sets the type of the current navigation type and updates the UI to match it. |
- * @param buttonType The type of navigation button to be shown. |
- */ |
- private void setNavigationButtonType(NavigationButtonType buttonType) { |
- switch (buttonType) { |
- case PAGE: |
- Drawable page = ApiCompatibilityUtils.getDrawable( |
- getResources(), R.drawable.ic_omnibox_page); |
- page.setColorFilter(mUseDarkColors |
- ? getResources().getColor(R.color.light_normal_color) |
- : Color.WHITE, PorterDuff.Mode.SRC_IN); |
- mNavigationButton.setImageDrawable(page); |
- break; |
- case MAGNIFIER: |
- mNavigationButton.setImageResource(R.drawable.ic_omnibox_magnifier); |
- break; |
- case EMPTY: |
- mNavigationButton.setImageResource(0); |
- break; |
- default: |
- assert false; |
- } |
- |
- if (mNavigationButton.getVisibility() != VISIBLE) { |
- mNavigationButton.setVisibility(VISIBLE); |
- } |
- mNavigationButtonType = buttonType; |
- updateLocationBarIconContainerVisibility(); |
- } |
- |
- /** |
- * Update the visibility of the location bar icon container based on the state of the |
- * security and navigation icons. |
- */ |
- protected void updateLocationBarIconContainerVisibility() { |
- boolean showContainer = |
- mSecurityButtonShown || mNavigationButtonType != NavigationButtonType.EMPTY; |
- findViewById(R.id.location_bar_icon).setVisibility(showContainer ? VISIBLE : GONE); |
- } |
- |
- private boolean isStoredArticle(String url) { |
- DomDistillerService domDistillerService = |
- DomDistillerServiceFactory.getForProfile(Profile.getLastUsedProfile()); |
- String entryIdFromUrl = DomDistillerUrlUtils.getValueForKeyInUrl(url, "entry_id"); |
- if (TextUtils.isEmpty(entryIdFromUrl)) return false; |
- return domDistillerService.hasEntry(entryIdFromUrl); |
- } |
- |
- /** |
- * Updates the layout params for the location bar start aligned views. |
- */ |
- protected void updateLayoutParams() { |
- int startMargin = 0; |
- int urlContainerChildIndex = -1; |
- for (int i = 0; i < getChildCount(); i++) { |
- View childView = getChildAt(i); |
- if (childView.getVisibility() != GONE) { |
- LayoutParams childLayoutParams = (LayoutParams) childView.getLayoutParams(); |
- if (ApiCompatibilityUtils.getMarginStart(childLayoutParams) != startMargin) { |
- ApiCompatibilityUtils.setMarginStart(childLayoutParams, startMargin); |
- childView.setLayoutParams(childLayoutParams); |
- } |
- if (childView == mUrlContainer) { |
- urlContainerChildIndex = i; |
- break; |
- } |
- int widthMeasureSpec; |
- int heightMeasureSpec; |
- if (childLayoutParams.width == LayoutParams.WRAP_CONTENT) { |
- widthMeasureSpec = MeasureSpec.makeMeasureSpec( |
- getMeasuredWidth(), MeasureSpec.AT_MOST); |
- } else if (childLayoutParams.width == LayoutParams.MATCH_PARENT) { |
- widthMeasureSpec = MeasureSpec.makeMeasureSpec( |
- getMeasuredWidth(), MeasureSpec.EXACTLY); |
- } else { |
- widthMeasureSpec = MeasureSpec.makeMeasureSpec( |
- childLayoutParams.width, MeasureSpec.EXACTLY); |
- } |
- if (childLayoutParams.height == LayoutParams.WRAP_CONTENT) { |
- heightMeasureSpec = MeasureSpec.makeMeasureSpec( |
- getMeasuredHeight(), MeasureSpec.AT_MOST); |
- } else if (childLayoutParams.height == LayoutParams.MATCH_PARENT) { |
- heightMeasureSpec = MeasureSpec.makeMeasureSpec( |
- getMeasuredHeight(), MeasureSpec.EXACTLY); |
- } else { |
- heightMeasureSpec = MeasureSpec.makeMeasureSpec( |
- childLayoutParams.height, MeasureSpec.EXACTLY); |
- } |
- childView.measure(widthMeasureSpec, heightMeasureSpec); |
- startMargin += childView.getMeasuredWidth(); |
- } |
- } |
- |
- assert urlContainerChildIndex != -1; |
- int urlContainerMarginEnd = 0; |
- for (int i = urlContainerChildIndex + 1; i < getChildCount(); i++) { |
- View childView = getChildAt(i); |
- if (childView.getVisibility() != GONE) { |
- LayoutParams childLayoutParams = (LayoutParams) childView.getLayoutParams(); |
- urlContainerMarginEnd = Math.max(urlContainerMarginEnd, |
- childLayoutParams.width |
- + ApiCompatibilityUtils.getMarginStart(childLayoutParams) |
- + ApiCompatibilityUtils.getMarginEnd(childLayoutParams)); |
- } |
- } |
- LayoutParams urlLayoutParams = (LayoutParams) mUrlContainer.getLayoutParams(); |
- if (ApiCompatibilityUtils.getMarginEnd(urlLayoutParams) != urlContainerMarginEnd) { |
- ApiCompatibilityUtils.setMarginEnd(urlLayoutParams, urlContainerMarginEnd); |
- mUrlContainer.setLayoutParams(urlLayoutParams); |
- } |
- } |
- |
- /** |
- * @return Whether the delete button should be shown. |
- */ |
- protected boolean shouldShowDeleteButton() { |
- // Show the delete button at the endon the right when the bar has focus and has some text. |
- return mUrlBar.hasFocus() && !TextUtils.isEmpty(mUrlBar.getText()); |
- } |
- |
- /** |
- * Updates the display of the delete URL content button. |
- */ |
- protected void updateDeleteButtonVisibility() { |
- } |
- |
- /** |
- * @return The suggestion list popup containing the omnibox results (or |
- * null if it has not yet been created). |
- */ |
- @VisibleForTesting |
- public OmniboxSuggestionsList getSuggestionList() { |
- return mSuggestionList; |
- } |
- |
- /** |
- * Initiates the mSuggestionListPopup. Done on demand to not slow down |
- * the initial inflation of the location bar. |
- */ |
- private void initSuggestionList() { |
- // Only called from onSuggestionsReceived(), which is a callback from a listener set up by |
- // onNativeLibraryReady(), so this assert is safe. |
- assert mNativeInitialized : "Trying to initialize suggestions list before native init"; |
- if (mSuggestionList != null) return; |
- |
- OnLayoutChangeListener suggestionListResizer = new OnLayoutChangeListener() { |
- @Override |
- public void onLayoutChange(View v, int left, int top, int right, int bottom, |
- int oldLeft, int oldTop, int oldRight, int oldBottom) { |
- // On ICS, this update does not take affect unless it is posted to the end of the |
- // current message queue. |
- post(new Runnable() { |
- @Override |
- public void run() { |
- if (mSuggestionList.isShown()) mSuggestionList.updateLayoutParams(); |
- } |
- }); |
- } |
- }; |
- getRootView().findViewById(R.id.control_container) |
- .addOnLayoutChangeListener(suggestionListResizer); |
- |
- mSuggestionList = new OmniboxSuggestionsList(getContext()); |
- mOmniboxResultsContainer.addView(mSuggestionList); |
- mSuggestionList.setAdapter(mSuggestionListAdapter); |
- mSuggestionList.setClipToPadding(false); |
- mSuggestionListAdapter.setSuggestionDelegate(new OmniboxSuggestionDelegate() { |
- @Override |
- public void onSelection(OmniboxSuggestion suggestion, int position) { |
- mSuggestionSelectionInProgress = true; |
- String suggestionMatchUrl = updateSuggestionUrlIfNeeded(suggestion, position); |
- loadUrlFromOmniboxMatch(suggestionMatchUrl, suggestion.getTransition(), position, |
- suggestion.getType()); |
- hideSuggestions(); |
- UiUtils.hideKeyboard(mUrlBar); |
- } |
- |
- @Override |
- public void onRefineSuggestion(OmniboxSuggestion suggestion) { |
- stopAutocomplete(false); |
- mUrlBar.setUrl(suggestion.getFillIntoEdit(), null); |
- mUrlBar.setSelection(mUrlBar.getText().length()); |
- RecordUserAction.record("MobileOmniboxRefineSuggestion"); |
- } |
- |
- @Override |
- public void onSetUrlToSuggestion(OmniboxSuggestion suggestion) { |
- if (mIgnoreOmniboxItemSelection) return; |
- setUrlBarText(null, null, suggestion.getFillIntoEdit()); |
- mUrlBar.setSelection(mUrlBar.getText().length()); |
- mIgnoreOmniboxItemSelection = true; |
- } |
- |
- @Override |
- public void onDeleteSuggestion(int position) { |
- if (mAutocomplete != null) mAutocomplete.deleteSuggestion(position); |
- } |
- |
- @Override |
- public void onGestureDown() { |
- stopAutocomplete(false); |
- } |
- |
- @Override |
- public void onShowModal() { |
- mSuggestionModalShown = true; |
- } |
- |
- @Override |
- public void onHideModal() { |
- mSuggestionModalShown = false; |
- } |
- |
- @Override |
- public void onTextWidthsUpdated(float requiredWidth, float matchContentsWidth) { |
- mSuggestionList.updateMaxTextWidths(requiredWidth, matchContentsWidth); |
- } |
- |
- @Override |
- public float getMaxRequiredWidth() { |
- return mSuggestionList.getMaxRequiredWidth(); |
- } |
- |
- @Override |
- public float getMaxMatchContentsWidth() { |
- return mSuggestionList.getMaxMatchContentsWidth(); |
- } |
- }); |
- } |
- |
- /** |
- * @return The view that the suggestion popup should be anchored below. |
- */ |
- protected View getSuggestionPopupAnchorView() { |
- return this; |
- } |
- |
- /** |
- * @return The background for the omnibox suggestions popup. |
- */ |
- protected Drawable getSuggestionPopupBackground() { |
- if (mToolbarDataProvider.isIncognito()) { |
- return new ColorDrawable(OMNIBOX_INCOGNITO_RESULTS_BG_COLOR); |
- } else { |
- return new ColorDrawable(OMNIBOX_RESULTS_BG_COLOR); |
- } |
- } |
- |
- /** |
- * Handles showing/hiding the suggestions list. |
- * @param visible Whether the suggestions list should be visible. |
- */ |
- protected void setSuggestionsListVisibility(final boolean visible) { |
- mSuggestionsShown = visible; |
- if (mSuggestionList != null) { |
- final boolean isShowing = mSuggestionList.isShown(); |
- if (visible && !isShowing) { |
- mSuggestionList.show(); |
- } else if (!visible && isShowing) { |
- mSuggestionList.setVisibility(GONE); |
- } |
- } |
- updateOmniboxResultsContainer(); |
- } |
- |
- /** |
- * Updates the URL we will navigate to from suggestion, if needed. This will update the search |
- * URL to be of the corpus type if query in the omnibox is displayed and update aqs= parameter |
- * on regular web search URLs. |
- * |
- * @param suggestion The chosen omnibox suggestion. |
- * @param selectedIndex The index of the chosen omnibox suggestion. |
- * @return The url to navigate to. |
- */ |
- private String updateSuggestionUrlIfNeeded(OmniboxSuggestion suggestion, int selectedIndex) { |
- // Only called once we have suggestions, and don't have a listener though which we can |
- // receive suggestions until the native side is ready, so this is safe |
- assert mNativeInitialized |
- : "updateSuggestionUrlIfNeeded called before native initialization"; |
- |
- String updatedUrl = null; |
- // Only replace URL queries for corpus search refinements, this does not work well |
- // for regular web searches. |
- // TODO(mariakhomenko): improve efficiency by just checking whether corpus exists. |
- if (mQueryInTheOmnibox && !suggestion.isUrlSuggestion() |
- && !TextUtils.isEmpty(mToolbarDataProvider.getCorpusChipText())) { |
- String query = suggestion.getFillIntoEdit(); |
- Tab currentTab = getCurrentTab(); |
- if (currentTab != null && !TextUtils.isEmpty(currentTab.getUrl()) |
- && !TextUtils.isEmpty(query)) { |
- updatedUrl = TemplateUrlService.getInstance().replaceSearchTermsInUrl( |
- query, currentTab.getUrl()); |
- } |
- } else if (suggestion.getType() != Type.VOICE_SUGGEST) { |
- // TODO(mariakhomenko): Ideally we want to update match destination URL with new aqs |
- // for query in the omnibox and voice suggestions, but it's currently difficult to do. |
- long elapsedTimeSinceInputChange = mNewOmniboxEditSessionTimestamp > 0 |
- ? (SystemClock.elapsedRealtime() - mNewOmniboxEditSessionTimestamp) : -1; |
- updatedUrl = mAutocomplete.updateMatchDestinationUrlWithQueryFormulationTime( |
- selectedIndex, elapsedTimeSinceInputChange); |
- } |
- |
- return updatedUrl == null ? suggestion.getUrl() : updatedUrl; |
- } |
- |
- private void clearSuggestions(boolean notifyChange) { |
- mSuggestionItems.clear(); |
- // Make sure to notify the adapter. If the ListView becomes out of sync |
- // with its adapter and it has not been notified, it will throw an |
- // exception when some UI events are propagated. |
- if (notifyChange) mSuggestionListAdapter.notifyDataSetChanged(); |
- } |
- |
- /** |
- * Hides the omnibox suggestion popup. |
- * |
- * <p> |
- * Signals the autocomplete controller to stop generating omnibox suggestions. |
- * |
- * @see AutocompleteController#stop(boolean) |
- */ |
- @Override |
- public void hideSuggestions() { |
- if (mAutocomplete == null) return; |
- |
- if (mShowSuggestions != null) removeCallbacks(mShowSuggestions); |
- |
- recordSuggestionsDismissed(); |
- |
- stopAutocomplete(true); |
- |
- setSuggestionsListVisibility(false); |
- clearSuggestions(true); |
- updateNavigationButton(); |
- |
- mSuggestionSelectionInProgress = false; |
- } |
- |
- /** |
- * Records a UMA action indicating that the user dismissed the suggestion list (e.g. pressed |
- * the back button or the 'x' button in the Omnibox). If there was an answer shown its type |
- * is recorded. |
- * |
- * The action is not recorded if mSelectionInProgress is true. This allows us to avoid |
- * recording the action in the case where the user is selecting a suggestion which is not |
- * considered a dismissal. |
- */ |
- private void recordSuggestionsDismissed() { |
- if (mSuggestionSelectionInProgress || mSuggestionItems.size() == 0) return; |
- |
- int answerTypeShown = 0; |
- for (int i = 0; i < mSuggestionItems.size(); i++) { |
- OmniboxSuggestion suggestion = mSuggestionItems.get(i).getSuggestion(); |
- if (suggestion.hasAnswer()) { |
- try { |
- answerTypeShown = Integer.parseInt(suggestion.getAnswerType()); |
- } catch (NumberFormatException e) { |
- Log.e(getClass().getSimpleName(), |
- "Answer type in dismissed suggestions is not an int: " |
- + suggestion.getAnswerType()); |
- } |
- break; |
- } |
- } |
- RecordHistogram.recordSparseSlowlyHistogram( |
- "Omnibox.SuggestionsDismissed.AnswerType", answerTypeShown); |
- } |
- |
- /** |
- * Signals the autocomplete controller to stop generating omnibox suggestions and cancels the |
- * queued task to start the autocomplete controller, if any. |
- * |
- * @param clear Whether to clear the most recent autocomplete results. |
- */ |
- private void stopAutocomplete(boolean clear) { |
- if (mAutocomplete != null) mAutocomplete.stop(clear); |
- cancelPendingAutocompleteStart(); |
- } |
- |
- /** |
- * Cancels the queued task to start the autocomplete controller, if any. |
- */ |
- private void cancelPendingAutocompleteStart() { |
- if (mRequestSuggestions != null) { |
- // There is a request for suggestions either waiting for the native side |
- // to start, or on the message queue. Remove it from wherever it is. |
- if (!mDeferredNativeRunnables.remove(mRequestSuggestions)) { |
- removeCallbacks(mRequestSuggestions); |
- } |
- mRequestSuggestions = null; |
- } |
- } |
- |
- @Override |
- protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { |
- // Don't restore the state of the location bar, it can lead to all kind of bad states with |
- // the popup. |
- // When we restore tabs, we focus the selected tab so the URL of the page shows. |
- } |
- |
- /** |
- * Performs a search query on the current {@link ChromeTab}. This calls |
- * {@link TemplateUrlService#getUrlForSearchQuery(String)} to get a url based on {@code query} |
- * and loads that url in the current {@link ChromeTab}. |
- * @param query The {@link String} that represents the text query that should be searched for. |
- */ |
- @VisibleForTesting |
- public void performSearchQueryForTest(String query) { |
- if (TextUtils.isEmpty(query)) return; |
- |
- String queryUrl = TemplateUrlService.getInstance().getUrlForSearchQuery(query); |
- |
- if (!TextUtils.isEmpty(queryUrl)) { |
- loadUrl(queryUrl, PageTransition.GENERATED); |
- } else { |
- setSearchQuery(query); |
- } |
- } |
- |
- /** |
- * Sets the query string in the omnibox (ensuring the URL bar has focus and triggering |
- * autocomplete for the specified query) as if the user typed it. |
- * |
- * @param query The query to be set in the omnibox. |
- */ |
- public void setSearchQuery(final String query) { |
- if (TextUtils.isEmpty(query)) return; |
- |
- if (!mNativeInitialized) { |
- mDeferredNativeRunnables.add(new Runnable() { |
- @Override |
- public void run() { |
- setSearchQuery(query); |
- } |
- }); |
- return; |
- } |
- |
- setUrlBarText(null, null, query); |
- mUrlBar.setSelection(0, mUrlBar.getText().length()); |
- mUrlBar.requestFocus(); |
- stopAutocomplete(false); |
- if (getCurrentTab() != null) { |
- mAutocomplete.start( |
- getCurrentTab().getProfile(), getCurrentTab().getUrl(), query, false); |
- } |
- post(new Runnable() { |
- @Override |
- public void run() { |
- UiUtils.showKeyboard(mUrlBar); |
- } |
- }); |
- } |
- |
- /** |
- * Whether {@code v} is a location icon which can be clicked to show the |
- * origin info dialog. |
- */ |
- private boolean isLocationIcon(View v) { |
- return v == mSecurityButton || v == mNavigationButton; |
- } |
- |
- @Override |
- public void onClick(View v) { |
- if (v == mDeleteButton) { |
- if (!TextUtils.isEmpty(mUrlBar.getQueryText())) { |
- setUrlBarText(null, null, ""); |
- hideSuggestions(); |
- } |
- |
- startZeroSuggest(); |
- return; |
- } else if (!mUrlHasFocus && isLocationIcon(v)) { |
- Tab currentTab = getCurrentTab(); |
- if (currentTab != null && currentTab.getWebContents() != null) { |
- WebsiteSettingsPopup.show(getContext(), currentTab.getProfile(), |
- currentTab.getWebContents()); |
- } |
- } else if (v == mMicButton) { |
- RecordUserAction.record("MobileOmniboxVoiceSearch"); |
- startVoiceRecognition(); |
- } |
- } |
- |
- /** |
- * Whether we want to be showing inline autocomplete results. We don't want to show them as the |
- * user deletes input. Also if there is a composition (e.g. while using the Japanese IME), |
- * we must not autocomplete or we'll destroy the composition. |
- * @return Whether we want to be showing inline autocomplete results. |
- */ |
- private boolean shouldAutocomplete() { |
- if (mLastUrlEditWasDelete) return false; |
- Editable text = mUrlBar.getText(); |
- |
- return mUrlBar.isCursorAtEndOfTypedText() |
- && !mUrlBar.isInBatchEditMode() |
- && BaseInputConnection.getComposingSpanEnd(text) |
- == BaseInputConnection.getComposingSpanStart(text); |
- } |
- |
- @Override |
- public void onSuggestionsReceived(List<OmniboxSuggestion> newSuggestions, |
- String inlineAutocompleteText) { |
- // This is a callback from a listener that is set up by onNativeLibraryReady, |
- // so can only be called once the native side is set up. |
- assert mNativeInitialized : "Suggestions received before native side intialialized"; |
- |
- if (getCurrentTab() == null) { |
- // If the current tab is not available, drop the suggestions and hide the autocomplete. |
- hideSuggestions(); |
- return; |
- } |
- |
- String userText = mUrlBar.getTextWithoutAutocomplete(); |
- mUrlTextAfterSuggestionsReceived = userText + inlineAutocompleteText; |
- |
- boolean itemsChanged = false; |
- boolean itemCountChanged = false; |
- // If the length of the incoming suggestions matches that of those currently being shown, |
- // replace them inline to allow transient entries to retain their proper highlighting. |
- if (mSuggestionItems.size() == newSuggestions.size()) { |
- for (int index = 0; index < newSuggestions.size(); index++) { |
- OmniboxResultItem suggestionItem = mSuggestionItems.get(index); |
- OmniboxSuggestion suggestion = suggestionItem.getSuggestion(); |
- OmniboxSuggestion newSuggestion = newSuggestions.get(index); |
- // Determine whether the suggestions have changed. If not, save some time by not |
- // redrawing the suggestions UI. |
- if (suggestion.equals(newSuggestion) |
- && suggestion.getType() != OmniboxSuggestion.Type.SEARCH_SUGGEST_TAIL) { |
- if (suggestionItem.getMatchedQuery().equals(userText)) { |
- continue; |
- } else if (!suggestion.getDisplayText().startsWith(userText) |
- && !suggestion.getUrl().contains(userText)) { |
- continue; |
- } |
- } |
- mSuggestionItems.set(index, new OmniboxResultItem(newSuggestion, userText)); |
- itemsChanged = true; |
- } |
- } else { |
- itemsChanged = true; |
- itemCountChanged = true; |
- clearSuggestions(false); |
- for (int i = 0; i < newSuggestions.size(); i++) { |
- mSuggestionItems.add(new OmniboxResultItem(newSuggestions.get(i), userText)); |
- } |
- } |
- |
- if (mSuggestionItems.isEmpty()) { |
- if (mSuggestionsShown) hideSuggestions(); |
- return; |
- } |
- |
- if (shouldAutocomplete()) { |
- mUrlBar.setAutocompleteText(userText, inlineAutocompleteText); |
- } |
- |
- // Show the suggestion list. |
- initSuggestionList(); // It may not have been initialized yet. |
- mSuggestionList.resetMaxTextWidths(); |
- |
- if (itemsChanged) mSuggestionListAdapter.notifySuggestionsChanged(); |
- |
- if (mUrlBar.hasFocus()) { |
- final boolean updateLayoutParams = itemCountChanged; |
- mShowSuggestions = new Runnable() { |
- @Override |
- public void run() { |
- setSuggestionsListVisibility(true); |
- if (updateLayoutParams) { |
- mSuggestionList.updateLayoutParams(); |
- } |
- mShowSuggestions = null; |
- } |
- }; |
- if (!isUrlFocusChangeInProgress()) { |
- mShowSuggestions.run(); |
- } else { |
- postDelayed(mShowSuggestions, ToolbarPhone.URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); |
- } |
- } |
- |
- // Update the navigation button to show the default suggestion's icon. |
- updateNavigationButton(); |
- |
- if (!CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_INSTANT) |
- && PrivacyPreferencesManager.getInstance(getContext()).shouldPrerender()) { |
- mOmniboxPrerender.prerenderMaybe( |
- userText, |
- getOriginalUrl(), |
- mAutocomplete.getCurrentNativeAutocompleteResult(), |
- getCurrentTab().getProfile(), |
- getCurrentTab()); |
- } |
- } |
- |
- @Override |
- public void backKeyPressed() { |
- hideSuggestions(); |
- UiUtils.hideKeyboard(mUrlBar); |
- // Revert the URL to match the current page. |
- setUrlToPageUrl(); |
- // Focus the page. |
- Tab currentTab = getCurrentTab(); |
- if (currentTab != null) currentTab.requestFocus(); |
- } |
- |
- /** |
- * @return Returns the original url of the page. |
- */ |
- public String getOriginalUrl() { |
- return mOriginalUrl; |
- } |
- |
- /** |
- * Given the URL display text, this will remove any path portion contained within. |
- * @param displayText The text to strip the path from. |
- * @return A pair where the first item is the text without any path content (if the path was |
- * successfully found), and the second item is the path content (or null if no path |
- * was found or parsing the path failed). |
- * @see ToolbarDataProvider#getText() |
- */ |
- // TODO(tedchoc): Move this logic into the original display text calculation. |
- @VisibleForTesting |
- public static Pair<String, String> splitPathFromUrlDisplayText(String displayText) { |
- int pathSearchOffset = 0; |
- Uri uri = Uri.parse(displayText); |
- String scheme = uri.getScheme(); |
- if (!TextUtils.isEmpty(scheme)) { |
- if (UNSUPPORTED_SCHEMES_TO_SPLIT.contains(scheme)) { |
- return Pair.create(displayText, null); |
- } else if (ACCEPTED_SCHEMES.contains(scheme)) { |
- for (pathSearchOffset = scheme.length(); |
- pathSearchOffset < displayText.length(); |
- pathSearchOffset++) { |
- char c = displayText.charAt(pathSearchOffset); |
- if (c != ':' && c != '/') break; |
- } |
- } |
- } |
- int pathOffset = -1; |
- if (pathSearchOffset < displayText.length()) { |
- pathOffset = displayText.indexOf('/', pathSearchOffset); |
- } |
- if (pathOffset != -1) { |
- String prePathText = displayText.substring(0, pathOffset); |
- // If the '/' is the last character and the beginning of the path, then just drop |
- // the path entirely. |
- String pathText = pathOffset == displayText.length() - 1 |
- ? null : displayText.substring(pathOffset); |
- return Pair.create(prePathText, pathText); |
- } |
- return Pair.create(displayText, null); |
- } |
- |
- /** |
- * Sets the displayed URL to be the URL of the page currently showing. |
- * |
- * <p>The URL is converted to the most user friendly format (removing HTTP:// for example). |
- * |
- * <p>If the current tab is null, the URL text will be cleared. |
- */ |
- @Override |
- public void setUrlToPageUrl() { |
- // If the URL is currently focused, do not replace the text they have entered with the URL. |
- // Once they stop editing the URL, the current tab's URL will automatically be filled in. |
- if (mUrlBar.hasFocus()) return; |
- |
- mQueryInTheOmnibox = false; |
- |
- if (getCurrentTab() == null) { |
- setUrlBarText(null, null, ""); |
- return; |
- } |
- |
- // Profile may be null if switching to a tab that has not yet been initialized. |
- Profile profile = getCurrentTab().getProfile(); |
- if (profile != null) mOmniboxPrerender.clear(profile); |
- |
- String url = getCurrentTab().getUrl().trim(); |
- mOriginalUrl = url; |
- |
- if (NativePageFactory.isNativePageUrl(url, getCurrentTab().isIncognito())) { |
- // Don't show anything for Chrome URLs. |
- setUrlBarText("", null, null); |
- return; |
- } |
- |
- // Background view has similar case as snapshot. |
- BackgroundContentViewHelper backgroundViewHelper = |
- getCurrentTab().getBackgroundContentViewHelper(); |
- boolean hasPendingBackgroundPage = |
- backgroundViewHelper != null && backgroundViewHelper.hasPendingBackgroundPage(); |
- boolean isTransitioningFromPreviewPageToOriginal = |
- showingOriginalUrlForPreview() && !hasPendingBackgroundPage; |
- mShowingOriginalUrlForPreview = hasPendingBackgroundPage; |
- |
- boolean showingQuery = false; |
- String displayText = mToolbarDataProvider.getText(); |
- int securityLevel = getSecurityLevel(); |
- if (securityLevel != ConnectionSecurityLevel.SECURITY_ERROR |
- && !TextUtils.isEmpty(displayText) && mToolbarDataProvider.wouldReplaceURL()) { |
- url = displayText.trim(); |
- showingQuery = true; |
- mQueryInTheOmnibox = true; |
- } |
- String path = null; |
- if (!showingQuery && FeatureUtilities.isDocumentMode(getContext())) { |
- Pair<String, String> urlText = splitPathFromUrlDisplayText(displayText); |
- displayText = urlText.first; |
- path = urlText.second; |
- } |
- |
- if (DomDistillerUrlUtils.isDistilledPage(url)) { |
- if (isStoredArticle(url)) { |
- DomDistillerService domDistillerService = |
- DomDistillerServiceFactory.getForProfile(profile); |
- String originalUrl = domDistillerService.getUrlForEntry( |
- DomDistillerUrlUtils.getValueForKeyInUrl(url, "entry_id")); |
- displayText = |
- DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl); |
- } else if (DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url) != null) { |
- String originalUrl = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); |
- displayText = |
- DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl); |
- } |
- } |
- |
- if (setUrlBarText(displayText, path, url) || isTransitioningFromPreviewPageToOriginal) { |
- mUrlBar.deEmphasizeUrl(); |
- emphasizeUrl(); |
- } |
- if (showingQuery) { |
- updateNavigationButton(); |
- } |
- updateCustomSelectionActionModeCallback(); |
- } |
- |
- /** |
- * Changes the text on the url bar |
- * @param displayText The text (URL or search terms) for user display. |
- * @param trailingText The trailing text (path portion of the URL) to be displayed separately. |
- * @param text The original text (URL or search terms) for copy/cut. |
- * @return Whether the URL was changed as a result of this call. |
- */ |
- private boolean setUrlBarText(String displayText, String trailingText, String text) { |
- mIgnoreURLBarModification = true; |
- boolean urlChanged = mUrlContainer.setUrlText(displayText, trailingText, text); |
- mIgnoreURLBarModification = false; |
- return urlChanged; |
- } |
- |
- /** |
- * Sets whether modifications to the URL bar should be ignored. |
- */ |
- @Override |
- public void setIgnoreURLBarModification(boolean value) { |
- mIgnoreURLBarModification = value; |
- } |
- |
- private void loadUrlFromOmniboxMatch(String url, int transition, int matchPosition, |
- OmniboxSuggestion.Type type) { |
- // loadUrl modifies AutocompleteController's state clearing the native |
- // AutocompleteResults needed by onSuggestionsSelected. Therefore, |
- // loadUrl should should be invoked last. |
- Tab currentTab = getCurrentTab(); |
- String currentPageUrl = currentTab != null ? currentTab.getUrl() : ""; |
- WebContents webContents = currentTab != null ? currentTab.getWebContents() : null; |
- long elapsedTimeSinceModified = mNewOmniboxEditSessionTimestamp > 0 |
- ? (SystemClock.elapsedRealtime() - mNewOmniboxEditSessionTimestamp) : -1; |
- mAutocomplete.onSuggestionSelected(matchPosition, type, currentPageUrl, |
- mQueryInTheOmnibox, mUrlFocusedFromFakebox, elapsedTimeSinceModified, |
- webContents); |
- loadUrl(url, transition); |
- } |
- |
- private void loadUrl(String url, int transition) { |
- Tab currentTab = getCurrentTab(); |
- |
- // The code of the rest of this class ensures that this can't be called until the native |
- // side is initialized |
- assert mNativeInitialized : "Loading URL before native side initialized"; |
- |
- if (currentTab != null |
- && (currentTab.isNativePage() || NewTabPage.isNTPUrl(currentTab.getUrl()))) { |
- NewTabPageUma.recordOmniboxNavigation(url, transition); |
- // Passing in an empty string should not do anything unless the user is at the NTP. |
- // Since the NTP has no url, pressing enter while clicking on the URL bar should refresh |
- // the page as it does when you click and press enter on any other site. |
- if (url.isEmpty()) url = currentTab.getUrl(); |
- } |
- |
- // Loads the |url| in the current ContentView and gives focus to the ContentView. |
- if (currentTab != null && !url.isEmpty()) { |
- LoadUrlParams loadUrlParams = new LoadUrlParams(url); |
- loadUrlParams.setVerbatimHeaders( |
- GeolocationHeader.getGeoHeader(getContext(), url, currentTab.isIncognito())); |
- loadUrlParams.setTransitionType(transition | PageTransition.FROM_ADDRESS_BAR); |
- currentTab.loadUrl(loadUrlParams); |
- |
- setUrlToPageUrl(); |
- RecordUserAction.record("MobileOmniboxSearch"); |
- RecordUserAction.record("MobileTabClobbered"); |
- } else { |
- setUrlToPageUrl(); |
- } |
- |
- if (currentTab != null) currentTab.requestFocus(); |
- |
- // Prevent any upcoming omnibox suggestions from showing. We have to do this after we load |
- // the URL as this will hide the suggestions and trigger a cancel of the prerendered page. |
- stopAutocomplete(true); |
- } |
- |
- /** |
- * Update the location bar visuals based on a loading state change. |
- * @param updateUrl Whether to update the URL as a result of the this call. |
- */ |
- @Override |
- public void updateLoadingState(boolean updateUrl) { |
- if (updateUrl) setUrlToPageUrl(); |
- updateNavigationButton(); |
- updateSecurityIcon(getSecurityLevel()); |
- } |
- |
- /** |
- * @return The ChromeTab currently showing. |
- */ |
- @Override |
- public ChromeTab getCurrentTab() { |
- if (mToolbarDataProvider == null) return null; |
- return ChromeTab.fromTab(mToolbarDataProvider.getTab()); |
- } |
- |
- private ContentViewCore getContentViewCore() { |
- Tab currentTab = getCurrentTab(); |
- return currentTab != null ? currentTab.getContentViewCore() : null; |
- } |
- |
- private void updateOmniboxResultsContainer() { |
- if (mSuggestionsShown || mUrlHasFocus) { |
- if (mOmniboxResultsContainer == null) { |
- ViewStub overlayStub = |
- (ViewStub) getRootView().findViewById(R.id.omnibox_results_container_stub); |
- mOmniboxResultsContainer = (ViewGroup) overlayStub.inflate(); |
- mOmniboxResultsContainer.setBackgroundColor(CONTENT_OVERLAY_COLOR); |
- // Prevent touch events from propagating down to the chrome view. |
- mOmniboxResultsContainer.setOnTouchListener(new OnTouchListener() { |
- @Override |
- @SuppressLint("ClickableViewAccessibility") |
- public boolean onTouch(View v, MotionEvent event) { |
- int action = event.getActionMasked(); |
- if (action == MotionEvent.ACTION_CANCEL |
- || action == MotionEvent.ACTION_UP) { |
- mUrlBar.clearFocus(); |
- updateOmniboxResultsContainerBackground(false); |
- } |
- return true; |
- } |
- }); |
- } |
- updateOmniboxResultsContainerVisibility(true); |
- } else if (mOmniboxResultsContainer != null) { |
- updateOmniboxResultsContainerBackground(false); |
- } |
- } |
- |
- private void updateOmniboxResultsContainerVisibility(boolean visible) { |
- boolean currentlyVisible = mOmniboxResultsContainer.getVisibility() == VISIBLE; |
- if (currentlyVisible == visible) { |
- // This early return is necessary. Otherwise, calling |
- // updateOmniboxResultsContainerVisibility(true) twice in a row will update |
- // mFocusedTabImportantForAccessibilityState incorrectly and cause |
- // mFocusedTabView to be stuck in IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS mode. |
- // http://crbug.com/445560 |
- return; |
- } |
- |
- if (visible) { |
- mOmniboxResultsContainer.setVisibility(VISIBLE); |
- |
- if (getContentViewCore() != null) { |
- mFocusedTabAccessibilityManager = |
- getContentViewCore().getBrowserAccessibilityManager(); |
- if (mFocusedTabAccessibilityManager != null) { |
- mFocusedTabAccessibilityManager.setVisible(false); |
- } |
- } |
- |
- if (getCurrentTab() != null && getCurrentTab().getView() != null) { |
- mFocusedTabView = getCurrentTab().getView(); |
- mFocusedTabImportantForAccessibilityState = |
- mFocusedTabView.getImportantForAccessibility(); |
- mFocusedTabView.setImportantForAccessibility( |
- IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); |
- } |
- } else { |
- mOmniboxResultsContainer.setVisibility(INVISIBLE); |
- |
- if (mFocusedTabAccessibilityManager != null) { |
- mFocusedTabAccessibilityManager.setVisible(true); |
- mFocusedTabAccessibilityManager = null; |
- } |
- |
- if (mFocusedTabView != null) { |
- mFocusedTabView.setImportantForAccessibility( |
- mFocusedTabImportantForAccessibilityState); |
- mFocusedTabView = null; |
- } |
- } |
- } |
- |
- /** |
- * Set the background of the omnibox results container. |
- * @param visible Whether the background should be made visible. |
- */ |
- private void updateOmniboxResultsContainerBackground(boolean visible) { |
- if (getToolbarDataProvider() == null) return; |
- |
- NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab(); |
- boolean locationBarShownInNTP = ntp != null && ntp.isLocationBarShownInNTP(); |
- if (visible) { |
- if (locationBarShownInNTP) { |
- mOmniboxResultsContainer.getBackground().setAlpha(0); |
- } else { |
- fadeInOmniboxResultsContainerBackground(); |
- } |
- } else { |
- if (locationBarShownInNTP) { |
- updateOmniboxResultsContainerVisibility(false); |
- } else { |
- fadeOutOmniboxResultsContainerBackground(); |
- } |
- } |
- } |
- |
- /** |
- * Trigger a fade in of the omnibox results background. |
- */ |
- protected void fadeInOmniboxResultsContainerBackground() { |
- if (mFadeInOmniboxBackgroundAnimator == null) { |
- mFadeInOmniboxBackgroundAnimator = ObjectAnimator.ofInt( |
- getRootView().findViewById(R.id.omnibox_results_container).getBackground(), |
- "alpha", 0, 255); |
- mFadeInOmniboxBackgroundAnimator.setDuration(OMNIBOX_CONTAINER_BACKGROUND_FADE_MS); |
- mFadeInOmniboxBackgroundAnimator.setInterpolator( |
- BakedBezierInterpolator.FADE_IN_CURVE); |
- } |
- runOmniboxResultsFadeAnimation(mFadeInOmniboxBackgroundAnimator); |
- } |
- |
- private void fadeOutOmniboxResultsContainerBackground() { |
- if (mFadeOutOmniboxBackgroundAnimator == null) { |
- mFadeOutOmniboxBackgroundAnimator = ObjectAnimator.ofInt( |
- getRootView().findViewById(R.id.omnibox_results_container).getBackground(), |
- "alpha", 255, 0); |
- mFadeOutOmniboxBackgroundAnimator.setDuration(OMNIBOX_CONTAINER_BACKGROUND_FADE_MS); |
- mFadeOutOmniboxBackgroundAnimator.setInterpolator( |
- BakedBezierInterpolator.FADE_OUT_CURVE); |
- mFadeOutOmniboxBackgroundAnimator.addListener(new AnimatorListenerAdapter() { |
- private boolean mIsCancelled; |
- |
- @Override |
- public void onAnimationStart(Animator animation) { |
- mIsCancelled = false; |
- } |
- |
- @Override |
- public void onAnimationCancel(Animator animation) { |
- mIsCancelled = true; |
- } |
- |
- @Override |
- public void onAnimationEnd(Animator animation) { |
- if (mIsCancelled) return; |
- updateOmniboxResultsContainerVisibility(false); |
- } |
- }); |
- } |
- runOmniboxResultsFadeAnimation(mFadeOutOmniboxBackgroundAnimator); |
- } |
- |
- private void runOmniboxResultsFadeAnimation(Animator fadeAnimation) { |
- if (mOmniboxBackgroundAnimator == fadeAnimation |
- && mOmniboxBackgroundAnimator.isRunning()) { |
- return; |
- } else if (mOmniboxBackgroundAnimator != null) { |
- mOmniboxBackgroundAnimator.cancel(); |
- } |
- mOmniboxBackgroundAnimator = fadeAnimation; |
- mOmniboxBackgroundAnimator.start(); |
- } |
- |
- /** |
- * @return Whether voice search is supported in the current browser configuration. |
- */ |
- protected boolean isVoiceSearchEnabled() { |
- return mToolbarDataProvider != null && !mToolbarDataProvider.isIncognito() |
- && FeatureUtilities.isRecognitionIntentPresent(getContext(), true); |
- } |
- |
- @Override |
- protected void onWindowVisibilityChanged(int visibility) { |
- super.onWindowVisibilityChanged(visibility); |
- if (visibility == View.VISIBLE) updateMicButtonState(); |
- } |
- |
- /** |
- * Call to notify the location bar that the state of the voice search microphone button may |
- * need to be updated. |
- */ |
- @Override |
- public void updateMicButtonState() { |
- mMicButton.setVisibility(isVoiceSearchEnabled() ? View.VISIBLE : View.GONE); |
- } |
- |
- /** |
- * Call to force the UI to update the state of various buttons based on whether or not the |
- * current tab is incognito. |
- */ |
- @Override |
- public void updateVisualsForState() { |
- if (updateUseDarkColors() || getToolbarDataProvider().isUsingBrandColor()) { |
- updateSecurityIcon(getSecurityLevel()); |
- } |
- ColorStateList colorStateList = getResources().getColorStateList(mUseDarkColors |
- ? R.color.dark_mode_tint : R.color.light_mode_tint); |
- mMicButton.setTint(colorStateList); |
- mDeleteButton.setTint(colorStateList); |
- |
- setNavigationButtonType(mNavigationButtonType); |
- mUrlContainer.setUseDarkTextColors(mUseDarkColors); |
- |
- if (mSuggestionList != null) { |
- mSuggestionList.setBackground(getSuggestionPopupBackground()); |
- } |
- mSuggestionListAdapter.setUseDarkColors(mUseDarkColors); |
- } |
- |
- /** |
- * Checks the current specs and updates {@link LocationBar#mUseDarkColors} if necessary. |
- * @return Whether {@link LocationBar#mUseDarkColors} has been updated. |
- */ |
- private boolean updateUseDarkColors() { |
- Tab tab = getCurrentTab(); |
- boolean brandColorNeedsLightText = false; |
- if (getToolbarDataProvider().isUsingBrandColor() && !mUrlHasFocus) { |
- int currentPrimaryColor = getToolbarDataProvider().getPrimaryColor(); |
- brandColorNeedsLightText = |
- BrandColorUtils.shouldUseLightDrawablesForToolbar(currentPrimaryColor); |
- } |
- |
- boolean useDarkColors = tab == null || !(tab.isIncognito() || brandColorNeedsLightText); |
- boolean hasChanged = useDarkColors != mUseDarkColors; |
- mUseDarkColors = useDarkColors; |
- |
- return hasChanged; |
- } |
- |
- /** |
- * Triggers a voice recognition intent to allow the user to specify a search query. |
- */ |
- @Override |
- public void startVoiceRecognition() { |
- Activity activity = mWindowAndroid.getActivity().get(); |
- if (activity == null) return; |
- |
- Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); |
- intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, |
- RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); |
- intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, |
- activity.getComponentName().flattenToString()); |
- intent.putExtra(RecognizerIntent.EXTRA_WEB_SEARCH_ONLY, true); |
- |
- if (mWindowAndroid.showCancelableIntent(intent, this, R.string.voice_search_error) < 0) { |
- // Requery whether or not the recognition intent can be handled. |
- FeatureUtilities.isRecognitionIntentPresent(activity, false); |
- updateMicButtonState(); |
- } |
- } |
- |
- // WindowAndroid.IntentCallback implementation: |
- @Override |
- public void onIntentCompleted(WindowAndroid window, int resultCode, |
- ContentResolver contentResolver, Intent data) { |
- if (resultCode != Activity.RESULT_OK) return; |
- if (data.getExtras() == null) return; |
- |
- VoiceResult topResult = mAutocomplete.onVoiceResults(data.getExtras()); |
- if (topResult == null) return; |
- |
- String topResultQuery = topResult.getMatch(); |
- if (TextUtils.isEmpty(topResultQuery)) return; |
- |
- if (topResult.getConfidence() < VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD) { |
- setSearchQuery(topResultQuery); |
- return; |
- } |
- |
- String url = AutocompleteController.nativeQualifyPartialURLQuery(topResultQuery); |
- if (url == null) { |
- url = TemplateUrlService.getInstance().getUrlForVoiceSearchQuery( |
- topResultQuery); |
- } |
- loadUrl(url, PageTransition.TYPED); |
- } |
- |
- /** |
- * Tracks how the URL bar was focused (i.e. from the omnibox or the fakebox) and records a UMA |
- * stat for this. Should be called whenever the URL bar gains or loses focus. |
- * @param hasFocus Whether the URL bar now has focus. |
- */ |
- private void updateFocusSource(boolean hasFocus) { |
- if (!hasFocus) { |
- mUrlFocusedFromFakebox = false; |
- mHasRecordedUrlFocusSource = false; |
- return; |
- } |
- |
- // Record UMA event for how the URL bar was focused. |
- assert !mHasRecordedUrlFocusSource; |
- if (mHasRecordedUrlFocusSource) return; |
- |
- Tab currentTab = getCurrentTab(); |
- if (currentTab == null) return; |
- |
- String url = currentTab.getUrl(); |
- if (mUrlFocusedFromFakebox) { |
- RecordUserAction.record("MobileFocusedFakeboxOnNtp"); |
- } else { |
- if (currentTab.isNativePage() && NewTabPage.isNTPUrl(url)) { |
- RecordUserAction.record("MobileFocusedOmniboxOnNtp"); |
- } else { |
- RecordUserAction.record("MobileFocusedOmniboxNotOnNtp"); |
- } |
- } |
- mHasRecordedUrlFocusSource = true; |
- } |
- |
- @Override |
- public void onTabLoadingNTP(NewTabPage ntp) { |
- ntp.setFakeboxDelegate(this); |
- } |
- |
- @Override |
- public View getContainerView() { |
- return this; |
- } |
- |
- @Override |
- public void setTitleToPageTitle() { } |
-} |