| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
|
| deleted file mode 100644
|
| index 8099d1beabc9bfdcd8c86cd79430628b08d24ae0..0000000000000000000000000000000000000000
|
| --- a/chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
|
| +++ /dev/null
|
| @@ -1,1248 +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.contextualsearch;
|
| -
|
| -import android.app.Activity;
|
| -import android.os.Handler;
|
| -import android.view.View;
|
| -import android.view.ViewGroup;
|
| -import android.view.ViewTreeObserver;
|
| -import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
|
| -
|
| -import org.chromium.base.ActivityState;
|
| -import org.chromium.base.ApplicationStatus;
|
| -import org.chromium.base.ApplicationStatus.ActivityStateListener;
|
| -import org.chromium.base.CalledByNative;
|
| -import org.chromium.base.SysUtils;
|
| -import org.chromium.base.VisibleForTesting;
|
| -import org.chromium.chrome.R;
|
| -import org.chromium.chrome.browser.ChromeActivity;
|
| -import org.chromium.chrome.browser.Tab;
|
| -import org.chromium.chrome.browser.WebContentsFactory;
|
| -import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchControl;
|
| -import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel.PanelState;
|
| -import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel.StateChangeReason;
|
| -import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanelDelegate;
|
| -import org.chromium.chrome.browser.contextualsearch.ContextualSearchSelectionController.SelectionType;
|
| -import org.chromium.chrome.browser.device.DeviceClassManager;
|
| -import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler;
|
| -import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.OverrideUrlLoadingResult;
|
| -import org.chromium.chrome.browser.externalnav.ExternalNavigationParams;
|
| -import org.chromium.chrome.browser.gsa.GSAContextDisplaySelection;
|
| -import org.chromium.chrome.browser.infobar.InfoBarContainer;
|
| -import org.chromium.chrome.browser.preferences.PrefServiceBridge;
|
| -import org.chromium.chrome.browser.tab.TabRedirectHandler;
|
| -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
|
| -import org.chromium.chrome.browser.tabmodel.TabModel;
|
| -import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
|
| -import org.chromium.chrome.browser.tabmodel.TabModelObserver;
|
| -import org.chromium.chrome.browser.tabmodel.TabModelSelector;
|
| -import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
|
| -import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
|
| -import org.chromium.components.navigation_interception.NavigationParams;
|
| -import org.chromium.components.web_contents_delegate_android.WebContentsDelegateAndroid;
|
| -import org.chromium.content.browser.ContentView;
|
| -import org.chromium.content.browser.ContentViewCore;
|
| -import org.chromium.content.browser.ContextualSearchClient;
|
| -import org.chromium.content_public.browser.GestureStateListener;
|
| -import org.chromium.content_public.browser.LoadUrlParams;
|
| -import org.chromium.content_public.browser.WebContents;
|
| -import org.chromium.content_public.browser.WebContentsObserver;
|
| -import org.chromium.content_public.common.TopControlsState;
|
| -import org.chromium.ui.base.WindowAndroid;
|
| -
|
| -import java.net.MalformedURLException;
|
| -import java.net.URL;
|
| -import java.util.regex.Pattern;
|
| -
|
| -import javax.annotation.Nullable;
|
| -
|
| -
|
| -/**
|
| - * Manager for the Contextual Search feature.
|
| - * This class keeps track of the status of Contextual Search and coordinates the control
|
| - * with the layout.
|
| - */
|
| -public class ContextualSearchManager extends ContextualSearchObservable
|
| - implements ContextualSearchManagementDelegate,
|
| - ContextualSearchNetworkCommunicator, ContextualSearchSelectionHandler,
|
| - ContextualSearchClient, ActivityStateListener {
|
| -
|
| - private static final String TAG = "ContextualSearch";
|
| -
|
| - private static final String CONTAINS_WORD_PATTERN = "(\\w|\\p{L}|\\p{N})+";
|
| -
|
| - // Max selection length must be limited or the entire request URL can go past the 2K limit.
|
| - private static final int MAX_SELECTION_LENGTH = 100;
|
| -
|
| - private static final boolean ALWAYS_USE_RESOLVED_SEARCH_TERM = true;
|
| - private static final boolean NEVER_USE_RESOLVED_SEARCH_TERM = false;
|
| -
|
| - private static final String INTENT_URL_PREFIX = "intent:";
|
| -
|
| - // The animation duration of a URL being promoted to a tab when triggered by an
|
| - // intercept navigation. This is faster than the standard tab promotion animation
|
| - // so that it completes before the navigation.
|
| - private static final long INTERCEPT_NAVIGATION_PROMOTION_ANIMATION_DURATION_MS = 40;
|
| -
|
| - // We blacklist this URL because malformed URLs may bring up this page.
|
| - private static final String BLACKLISTED_URL = "about:blank";
|
| -
|
| - private final ContextualSearchSelectionController mSelectionController;
|
| - private final Pattern mContainsWordPattern;
|
| - private final ChromeActivity mActivity;
|
| - private ViewGroup mParentView;
|
| - private final ViewTreeObserver.OnGlobalFocusChangeListener mOnFocusChangeListener;
|
| -
|
| - private final WindowAndroid mWindowAndroid;
|
| - private ContentViewCore mSearchContentViewCore;
|
| - private WebContentsObserver mSearchWebContentsObserver;
|
| - private final WebContentsDelegateAndroid mWebContentsDelegate;
|
| - private ContextualSearchContentViewDelegate mSearchContentViewDelegate;
|
| - private final ContextualSearchTabPromotionDelegate mTabPromotionDelegate;
|
| - private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
|
| - private TabModelObserver mTabModelObserver;
|
| - private boolean mIsSearchContentViewShowing;
|
| - private boolean mDidLoadResolvedSearchRequest;
|
| - private long mLoadedSearchUrlTimeMs;
|
| - // TODO(donnd): consider changing this member's name to indicate "opened" instead of "seen".
|
| - private boolean mWereSearchResultsSeen;
|
| - private boolean mWereInfoBarsHidden;
|
| - private boolean mDidLoadAnyUrl;
|
| - private boolean mDidPromoteSearchNavigation;
|
| - private boolean mDidBasePageLoadJustStart;
|
| - private boolean mWasActivatedByTap;
|
| - private boolean mIsInitialized;
|
| -
|
| - private boolean mIsShowingPromo;
|
| - private boolean mDidLogPromoOutcome;
|
| -
|
| - /**
|
| - * Whether contextual search manager is currently promoting a tab. We should be ignoring hide
|
| - * requests when mIsPromotingTab is set to true.
|
| - */
|
| - private boolean mIsPromotingToTab;
|
| -
|
| - private ContextualSearchNetworkCommunicator mNetworkCommunicator;
|
| - private ContextualSearchPanelDelegate mSearchPanelDelegate;
|
| -
|
| - // TODO(pedrosimonetti): also store selected text, surroundings, url, bounding rect of selected
|
| - // text, and make sure that all states are cleared when starting a new contextual search to
|
| - // avoid having the values in a funky state.
|
| - private ContextualSearchRequest mSearchRequest;
|
| -
|
| - // The native manager associated with this object.
|
| - private long mNativeContextualSearchManagerPtr;
|
| -
|
| - private TabRedirectHandler mTabRedirectHandler;
|
| -
|
| - /**
|
| - * The delegate that is notified when the Search Panel ContentViewCore is ready to be rendered.
|
| - */
|
| - public interface ContextualSearchContentViewDelegate {
|
| - /**
|
| - * Sets the {@code ContentViewCore} associated to the Contextual Search Panel.
|
| - * @param contentViewCore Reference to the ContentViewCore.
|
| - */
|
| - void setContextualSearchContentViewCore(ContentViewCore contentViewCore);
|
| -
|
| - /**
|
| - * Releases the {@code ContentViewCore} associated to the Contextual Search Panel.
|
| - */
|
| - void releaseContextualSearchContentViewCore();
|
| - }
|
| -
|
| - /**
|
| - * The delegate that is responsible for promoting a {@link ContentViewCore} to a {@link Tab}
|
| - * when necessary.
|
| - */
|
| - public interface ContextualSearchTabPromotionDelegate {
|
| - /**
|
| - * Called when {@code searchContentViewCore} should be promoted to a {@link Tab}.
|
| - * @param searchContentViewCore The {@link ContentViewCore} to promote.
|
| - * @return Whether or not {@code searchContentViewCore}'s ownership
|
| - * was transferred to the new {@link Tab} or not. If
|
| - * {@code false}, this {@link ContentViewCore} might be
|
| - * destroyed after this call.
|
| - */
|
| - boolean createContextualSearchTab(ContentViewCore searchContentViewCore);
|
| - }
|
| -
|
| - /**
|
| - * Constructs the manager for the given activity, and will attach views to the given parent.
|
| - * @param activity The {@code ChromeActivity} in use.
|
| - * @param windowAndroid The {@code WindowAndroid} associated with Chrome.
|
| - * @param tabPromotionDelegate The {@link ContextualSearchTabPromotionDelegate} that is
|
| - * responsible for building tabs from contextual search
|
| - * {@link ContentViewCore}s.
|
| - */
|
| - public ContextualSearchManager(ChromeActivity activity, WindowAndroid windowAndroid,
|
| - ContextualSearchTabPromotionDelegate tabPromotionDelegate) {
|
| - super(activity);
|
| - mActivity = activity;
|
| - mWindowAndroid = windowAndroid;
|
| - mTabPromotionDelegate = tabPromotionDelegate;
|
| - mContainsWordPattern = Pattern.compile(CONTAINS_WORD_PATTERN);
|
| -
|
| - mSelectionController = new ContextualSearchSelectionController(activity, this);
|
| -
|
| - mWebContentsDelegate = new WebContentsDelegateAndroid() {
|
| - @Override
|
| - public void onLoadStarted() {
|
| - super.onLoadStarted();
|
| - mSearchPanelDelegate.onLoadStarted();
|
| - }
|
| -
|
| - @Override
|
| - public void onLoadStopped() {
|
| - super.onLoadStopped();
|
| - mSearchPanelDelegate.onLoadStopped();
|
| - }
|
| -
|
| - @Override
|
| - public void onLoadProgressChanged(int progress) {
|
| - super.onLoadProgressChanged(progress);
|
| - mSearchPanelDelegate.onLoadProgressChanged(progress);
|
| - }
|
| - };
|
| -
|
| - final View controlContainer = mActivity.findViewById(R.id.control_container);
|
| - mOnFocusChangeListener = new OnGlobalFocusChangeListener() {
|
| - @Override
|
| - public void onGlobalFocusChanged(View oldFocus, View newFocus) {
|
| - if (controlContainer != null && controlContainer.hasFocus()) {
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - }
|
| - }
|
| - };
|
| -
|
| - mTabModelObserver = new EmptyTabModelObserver() {
|
| - @Override
|
| - public void didAddTab(Tab tab, TabLaunchType type) {
|
| - // If we're in the process of promoting this tab, just return and don't mess with
|
| - // this state.
|
| - if (tab.getContentViewCore() == mSearchContentViewCore) return;
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - }
|
| - };
|
| - }
|
| -
|
| - /**
|
| - * Initializes this manager. Must be called before {@link #getContextualSearchControl()}.
|
| - * @param parentView The parent view to attach Contextual Search UX to.
|
| - */
|
| - public void initialize(ViewGroup parentView) {
|
| - mParentView = parentView;
|
| - mParentView.getViewTreeObserver().addOnGlobalFocusChangeListener(mOnFocusChangeListener);
|
| - mNativeContextualSearchManagerPtr = nativeInit();
|
| - listenForHideNotifications();
|
| - mTabRedirectHandler = new TabRedirectHandler(mActivity);
|
| -
|
| - mIsShowingPromo = false;
|
| - mDidLogPromoOutcome = false;
|
| - mDidLoadResolvedSearchRequest = false;
|
| - mWereSearchResultsSeen = false;
|
| - mNetworkCommunicator = this;
|
| - ApplicationStatus.registerStateListenerForActivity(this, mActivity);
|
| - mIsInitialized = true;
|
| - }
|
| -
|
| - /**
|
| - * Destroys the native Contextual Search Manager.
|
| - * Call this method before orphaning this object to allow it to be garbage collected.
|
| - */
|
| - public void destroy() {
|
| - if (!mIsInitialized) return;
|
| -
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - mParentView.getViewTreeObserver().removeOnGlobalFocusChangeListener(mOnFocusChangeListener);
|
| - nativeDestroy(mNativeContextualSearchManagerPtr);
|
| - stopListeningForHideNotifications();
|
| - mTabRedirectHandler.clear();
|
| - ApplicationStatus.unregisterActivityStateListener(this);
|
| - }
|
| -
|
| - @Override
|
| - public void setContextualSearchPanelDelegate(ContextualSearchPanelDelegate delegate) {
|
| - mSearchPanelDelegate = delegate;
|
| - }
|
| -
|
| - /**
|
| - * @return The {@link ContextualSearchPanelDelegate}, for testing purposes only.
|
| - */
|
| - @VisibleForTesting
|
| - public ContextualSearchPanelDelegate getContextualSearchPanelDelegate() {
|
| - return mSearchPanelDelegate;
|
| - }
|
| -
|
| - /**
|
| - * Sets the selection controller for testing purposes.
|
| - */
|
| - @VisibleForTesting
|
| - ContextualSearchSelectionController getSelectionController() {
|
| - return mSelectionController;
|
| - }
|
| -
|
| - @VisibleForTesting
|
| - boolean isSearchPanelShowing() {
|
| - return mSearchPanelDelegate.isShowing();
|
| - }
|
| -
|
| - /**
|
| - * @return Whether the Search Panel is opened. That is, whether it is EXPANDED or MAXIMIZED.
|
| - */
|
| - public boolean isSearchPanelOpened() {
|
| - PanelState state = mSearchPanelDelegate.getPanelState();
|
| - return state == PanelState.EXPANDED || state == PanelState.MAXIMIZED;
|
| - }
|
| -
|
| - /**
|
| - * @return The Base Page's {@link ContentViewCore}.
|
| - */
|
| - @Nullable private ContentViewCore getBaseContentView() {
|
| - return mSelectionController.getBaseContentView();
|
| - }
|
| -
|
| - @Override
|
| - public void setPreferenceState(boolean enabled) {
|
| - PrefServiceBridge.getInstance().setContextualSearchState(enabled);
|
| - }
|
| -
|
| - @Override
|
| - public boolean isPromoAvailable() {
|
| - return mPolicy.isPromoAvailable();
|
| - }
|
| -
|
| - /**
|
| - * Hides the Contextual Search UX.
|
| - * @param reason The {@link StateChangeReason} for hiding Contextual Search.
|
| - */
|
| - public void hideContextualSearch(StateChangeReason reason) {
|
| - if (mSearchPanelDelegate == null) return;
|
| -
|
| - if (mSearchPanelDelegate.isShowing()) {
|
| - mSearchPanelDelegate.closePanel(reason, false);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onCloseContextualSearch() {
|
| - if (mSearchPanelDelegate == null) return;
|
| -
|
| - // NOTE(pedrosimonetti): hideContextualSearch() will also be called after swiping the
|
| - // Panel down in order to dismiss it. In this case, hideContextualSearch() will be called
|
| - // after completing the hide animation, and at that moment the Panel will not be showing
|
| - // anymore. Therefore, we need to always clear selection, regardless of when the Panel
|
| - // was still visible, in order to make sure the selection will be cleared appropriately.
|
| - if (mSelectionController.getSelectionType() == SelectionType.TAP) {
|
| - mSelectionController.clearSelection();
|
| - }
|
| -
|
| - // Show the infobar container if it was visible before Contextual Search was shown.
|
| - if (mWereInfoBarsHidden) {
|
| - mWereInfoBarsHidden = false;
|
| - InfoBarContainer container = getInfoBarContainer();
|
| - if (container != null) {
|
| - container.setVisibility(View.VISIBLE);
|
| - container.setDoStayInvisible(false);
|
| - }
|
| - }
|
| -
|
| - if (!mWereSearchResultsSeen && mLoadedSearchUrlTimeMs != 0L) {
|
| - removeLastSearchVisit();
|
| - }
|
| -
|
| - // Clear the timestamp. This is to avoid future calls to hideContextualSearch clearing
|
| - // the current URL.
|
| - mLoadedSearchUrlTimeMs = 0L;
|
| - mWereSearchResultsSeen = false;
|
| -
|
| - mNetworkCommunicator.destroySearchContentView();
|
| - mSearchRequest = null;
|
| -
|
| - if (mIsShowingPromo && !mDidLogPromoOutcome) {
|
| - logPromoOutcome();
|
| - }
|
| -
|
| - mIsShowingPromo = false;
|
| - mSearchPanelDelegate.setIsPromoActive(false);
|
| - notifyHideContextualSearch();
|
| - }
|
| -
|
| - /**
|
| - * Called when the system back button is pressed. Will hide the layout.
|
| - */
|
| - public boolean onBackPressed() {
|
| - if (!mIsInitialized || !mSearchPanelDelegate.isShowing()) return false;
|
| - hideContextualSearch(StateChangeReason.BACK_PRESS);
|
| - return true;
|
| - }
|
| -
|
| - /**
|
| - * Called when the orientation of the device changes.
|
| - */
|
| - public void onOrientationChange() {
|
| - if (!mIsInitialized) return;
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - }
|
| -
|
| - /**
|
| - * Sets the {@link ContextualSearchNetworkCommunicator} to use for server requests.
|
| - * @param networkCommunicator The communicator for all future requests.
|
| - */
|
| - @VisibleForTesting
|
| - public void setNetworkCommunicator(ContextualSearchNetworkCommunicator networkCommunicator) {
|
| - mNetworkCommunicator = networkCommunicator;
|
| - }
|
| -
|
| - /**
|
| - * Determines if the given selection is valid or not.
|
| - * @param selection The selection portion of the context.
|
| - * @return whether the given selection is considered a valid target for a search.
|
| - */
|
| - private boolean isValidSelection(String selection) {
|
| - return isValidSelection(selection, getBaseContentView());
|
| - }
|
| -
|
| - @VisibleForTesting
|
| - boolean isValidSelection(String selection, ContentViewCore baseContentView) {
|
| - if (selection.length() > MAX_SELECTION_LENGTH || !doesContainAWord(selection)) {
|
| - return false;
|
| - }
|
| - return (baseContentView != null) && !baseContentView.isFocusedNodeEditable();
|
| - }
|
| -
|
| - /**
|
| - * Shows the Contextual Search UX.
|
| - * Calls back into onGetContextualSearchQueryResponse.
|
| - * @param stateChangeReason The reason explaining the change of state.
|
| - */
|
| - private void showContextualSearch(StateChangeReason stateChangeReason) {
|
| - if (!mSearchPanelDelegate.isShowing()) {
|
| - // If visible, hide the infobar container before showing the Contextual Search panel.
|
| - InfoBarContainer container = getInfoBarContainer();
|
| - if (container != null && container.getVisibility() == View.VISIBLE) {
|
| - mWereInfoBarsHidden = true;
|
| - container.setVisibility(View.INVISIBLE);
|
| - container.setDoStayInvisible(true);
|
| - }
|
| - }
|
| -
|
| - // If the user is jumping from one unseen search to another search, remove the last search
|
| - // from history.
|
| - PanelState state = mSearchPanelDelegate.getPanelState();
|
| - if (!mWereSearchResultsSeen && mLoadedSearchUrlTimeMs != 0L
|
| - && state != PanelState.UNDEFINED && state != PanelState.CLOSED) {
|
| - removeLastSearchVisit();
|
| - }
|
| -
|
| - // Make sure we'll create a new Content View when needed.
|
| - mNetworkCommunicator.destroySearchContentView();
|
| -
|
| - boolean isTap = mSelectionController.getSelectionType() == SelectionType.TAP;
|
| - boolean didRequestSurroundings = false;
|
| - if (isTap && mPolicy.shouldPreviousTapResolve(
|
| - mNetworkCommunicator.getBasePageUrl())) {
|
| - mNetworkCommunicator.startSearchTermResolutionRequest(
|
| - mSelectionController.getSelectedText());
|
| - didRequestSurroundings = true;
|
| - } else {
|
| - boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(isTap);
|
| - mSearchRequest = new ContextualSearchRequest(mSelectionController.getSelectedText(),
|
| - null, shouldPrefetch);
|
| - mDidLoadResolvedSearchRequest = false;
|
| - getContextualSearchControl().setCentralText(mSelectionController.getSelectedText());
|
| - if (shouldPrefetch) loadSearchUrl();
|
| - }
|
| -
|
| - if (!didRequestSurroundings) {
|
| - // Gather surrounding text for Icing integration, which will make the selection and
|
| - // a shorter version of the surroundings available for Conversational Search.
|
| - // Although the surroundings are extracted, they will not be sent to the server as
|
| - // part of search term resolution, just sent to Icing which keeps them local until
|
| - // the user activates a Voice Search.
|
| - nativeGatherSurroundingText(mNativeContextualSearchManagerPtr,
|
| - mSelectionController.getSelectedText(), NEVER_USE_RESOLVED_SEARCH_TERM,
|
| - getBaseContentView(), mPolicy.maySendBasePageUrl());
|
| - }
|
| -
|
| - mWereSearchResultsSeen = false;
|
| -
|
| - // TODO(donnd): although we are showing the bar here, we have not yet set the text!
|
| - // Refactor to show the bar and set the text at the same time!
|
| - // TODO(donnd): If there was a previously ongoing contextual search, we should ensure
|
| - // it's registered as closed.
|
| - mSearchPanelDelegate.peekPanel(stateChangeReason);
|
| -
|
| - // Note: now that the contextual search has properly started, set the promo involvement.
|
| - if (mPolicy.isPromoAvailable()) {
|
| - mIsShowingPromo = true;
|
| - mDidLogPromoOutcome = false;
|
| - mSearchPanelDelegate.setIsPromoActive(true);
|
| - mSearchPanelDelegate.setDidSearchInvolvePromo();
|
| - }
|
| -
|
| - assert mSelectionController.getSelectionType() != SelectionType.UNDETERMINED;
|
| - mWasActivatedByTap = mSelectionController.getSelectionType() == SelectionType.TAP;
|
| - }
|
| -
|
| - @Override
|
| - public void startSearchTermResolutionRequest(String selection) {
|
| - ContentViewCore baseContentView = getBaseContentView();
|
| - if (baseContentView != null) {
|
| - nativeStartSearchTermResolutionRequest(mNativeContextualSearchManagerPtr, selection,
|
| - ALWAYS_USE_RESOLVED_SEARCH_TERM, getBaseContentView(),
|
| - mPolicy.maySendBasePageUrl());
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - @Nullable public URL getBasePageUrl() {
|
| - ContentViewCore baseContentViewCore = getBaseContentView();
|
| - if (baseContentViewCore == null) return null;
|
| -
|
| - try {
|
| - return new URL(baseContentViewCore.getWebContents().getUrl());
|
| - } catch (MalformedURLException e) {
|
| - return null;
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void updateTopControlsState(int current, boolean animate) {
|
| - Tab currentTab = mActivity.getActivityTab();
|
| - if (currentTab != null) {
|
| - currentTab.updateTopControlsState(current, animate);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Determines if the given selection contains a word or not.
|
| - * @param selection The the selection to check for a word.
|
| - * @return Whether the selection contains a word anywhere within it or not.
|
| - */
|
| - @VisibleForTesting
|
| - public boolean doesContainAWord(String selection) {
|
| - return mContainsWordPattern.matcher(selection).find();
|
| - }
|
| -
|
| - /**
|
| - * Accessor for the {@code InfoBarContainer} currently attached to the {@code Tab}.
|
| - */
|
| - private InfoBarContainer getInfoBarContainer() {
|
| - Tab tab = mActivity.getActivityTab();
|
| - return tab == null ? null : tab.getInfoBarContainer();
|
| - }
|
| -
|
| - /**
|
| - * Inflates the Contextual Search control, if needed.
|
| - */
|
| - private ContextualSearchControl getContextualSearchControl() {
|
| - return mSearchPanelDelegate.getContextualSearchControl();
|
| - }
|
| -
|
| - /**
|
| - * Listens for notifications that should hide the Contextual Search bar.
|
| - */
|
| - private void listenForHideNotifications() {
|
| - TabModelSelector selector = mActivity.getTabModelSelector();
|
| -
|
| - mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(selector) {
|
| - @Override
|
| - public void onPageLoadStarted(Tab tab, String url) {
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - mDidBasePageLoadJustStart = true;
|
| - }
|
| -
|
| - @Override
|
| - public void onCrash(Tab tab, boolean sadTabShown) {
|
| - if (sadTabShown) {
|
| - // Hide contextual search if the foreground tab crashed
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onClosingStateChanged(Tab tab, boolean closing) {
|
| - if (closing) hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - }
|
| - };
|
| -
|
| - for (TabModel tabModel : selector.getModels()) {
|
| - tabModel.addObserver(mTabModelObserver);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Stops listening for notifications that should hide the Contextual Search bar.
|
| - */
|
| - private void stopListeningForHideNotifications() {
|
| - if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
|
| -
|
| - TabModelSelector selector = mActivity.getTabModelSelector();
|
| - if (selector != null) {
|
| - for (TabModel tabModel : selector.getModels()) {
|
| - tabModel.removeObserver(mTabModelObserver);
|
| - }
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onActivityStateChange(Activity activity, int newState) {
|
| - if (newState == ActivityState.RESUMED || newState == ActivityState.STOPPED
|
| - || newState == ActivityState.DESTROYED) {
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - } else if (newState == ActivityState.PAUSED) {
|
| - mPolicy.logCurrentState(getBaseContentView());
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Clears our private member referencing the native manager.
|
| - */
|
| - @CalledByNative
|
| - public void clearNativeManager() {
|
| - assert mNativeContextualSearchManagerPtr != 0;
|
| - mNativeContextualSearchManagerPtr = 0;
|
| - }
|
| -
|
| - /**
|
| - * Sets our private member referencing the native manager.
|
| - * @param nativeManager The pointer to the native Contextual Search manager.
|
| - */
|
| - @CalledByNative
|
| - public void setNativeManager(long nativeManager) {
|
| - assert mNativeContextualSearchManagerPtr == 0;
|
| - mNativeContextualSearchManagerPtr = nativeManager;
|
| - }
|
| -
|
| - /**
|
| - * Called when surrounding text is available.
|
| - * @param beforeText to be shown before the selected word.
|
| - * @param afterText to be shown after the selected word.
|
| - */
|
| - @CalledByNative
|
| - private void onSurroundingTextAvailable(final String beforeText, final String afterText) {
|
| - if (mSearchPanelDelegate.isShowing()) {
|
| - getContextualSearchControl().setSearchContext(
|
| - mSelectionController.getSelectedText(), beforeText, afterText);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Called by native code when a selection is available to share with Icing (for Conversational
|
| - * Search).
|
| - */
|
| - @CalledByNative
|
| - private void onIcingSelectionAvailable(
|
| - final String encoding, final String surroundingText, int startOffset, int endOffset) {
|
| - GSAContextDisplaySelection selection =
|
| - new GSAContextDisplaySelection(encoding, surroundingText, startOffset, endOffset);
|
| - notifyShowContextualSearch(selection, mNetworkCommunicator.getBasePageUrl());
|
| - }
|
| -
|
| - /**
|
| - * Called in response to the
|
| - * {@link ContextualSearchManager#nativeStartSearchTermResolutionRequest} method.
|
| - * @param isNetworkUnavailable Indicates if the network is unavailable, in which case all other
|
| - * parameters should be ignored.
|
| - * @param responseCode The HTTP response code. If the code is not OK, the query
|
| - * should be ignored.
|
| - * @param searchTerm The term to use in our subsequent search.
|
| - * @param displayText The text to display in our UX.
|
| - * @param alternateTerm The alternate term to display on the results page.
|
| - */
|
| - @CalledByNative
|
| - public void onSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
|
| - final String searchTerm, final String displayText, final String alternateTerm,
|
| - boolean doPreventPreload) {
|
| - mNetworkCommunicator.handleSearchTermResolutionResponse(isNetworkUnavailable, responseCode,
|
| - searchTerm, displayText, alternateTerm, doPreventPreload);
|
| - }
|
| -
|
| - @Override
|
| - public void handleSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
|
| - String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload) {
|
| - if (!mSearchPanelDelegate.isShowing()) return;
|
| -
|
| - // Show an appropriate message for what to search for.
|
| - String message;
|
| - boolean doLiteralSearch = false;
|
| - if (isNetworkUnavailable) {
|
| - message = mActivity.getResources().getString(
|
| - R.string.contextual_search_network_unavailable);
|
| - } else if (!isHttpFailureCode(responseCode)) {
|
| - message = displayText;
|
| - } else if (!mPolicy.shouldShowErrorCodeInBar()) {
|
| - message = mSelectionController.getSelectedText();
|
| - doLiteralSearch = true;
|
| - } else {
|
| - message = mActivity.getResources().getString(
|
| - R.string.contextual_search_error, responseCode);
|
| - doLiteralSearch = true;
|
| - }
|
| - getContextualSearchControl().setCentralText(message);
|
| -
|
| - // If there was an error, fall back onto a literal search for the selection.
|
| - // Since we're showing the panel, there must be a selection.
|
| - if (doLiteralSearch) {
|
| - searchTerm = mSelectionController.getSelectedText();
|
| - alternateTerm = null;
|
| - doPreventPreload = true;
|
| - }
|
| - if (!searchTerm.isEmpty()) {
|
| - // TODO(donnd): Instead of preloading, we should prefetch (ie the URL should not
|
| - // appear in the user's history until the user views it). See crbug.com/406446.
|
| - boolean shouldPreload = !doPreventPreload && mPolicy.shouldPrefetchSearchResult(true);
|
| - mSearchRequest = new ContextualSearchRequest(searchTerm, alternateTerm, shouldPreload);
|
| - mDidLoadResolvedSearchRequest = false;
|
| - if (mIsSearchContentViewShowing) {
|
| - mSearchRequest.setNormalPriority();
|
| - }
|
| - if (mIsSearchContentViewShowing || shouldPreload) {
|
| - loadSearchUrl();
|
| - }
|
| - mPolicy.logSearchTermResolutionDetails(searchTerm,
|
| - mNetworkCommunicator.getBasePageUrl());
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Loads a Search Request in the Contextual Search's Content View.
|
| - */
|
| - private void loadSearchUrl() {
|
| - mLoadedSearchUrlTimeMs = System.currentTimeMillis();
|
| - mNetworkCommunicator.loadUrl(mSearchRequest.getSearchUrl());
|
| - mDidLoadResolvedSearchRequest = true;
|
| -
|
| - // TODO(pedrosimonetti): If the user taps on a word and quickly after that taps on the
|
| - // peeking Search Bar, the Search Content View will not be displayed. It seems that
|
| - // calling ContentViewCore.onShow() while it's being created has no effect. Need
|
| - // to coordinate with Chrome-Android folks to come up with a proper fix for this.
|
| - // For now, we force the ContentView to be displayed by calling onShow() again
|
| - // when a URL is being loaded. See: crbug.com/398206
|
| - if (mIsSearchContentViewShowing && mSearchContentViewCore != null) {
|
| - mSearchContentViewCore.onShow();
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * @return Whether a Tap gesture is currently supported.
|
| - */
|
| - private boolean isTapSupported() {
|
| - // Base page just started navigating away, so taps should be ignored.
|
| - if (mDidBasePageLoadJustStart) return false;
|
| -
|
| - return mPolicy.isTapSupported();
|
| - }
|
| -
|
| - // --------------------------------------------------------------------------------------------
|
| - // Search Content View
|
| - // --------------------------------------------------------------------------------------------
|
| -
|
| - /**
|
| - * Gets the {@code ContentViewCore} associated with Contextual Search Panel.
|
| - * @return Contextual Search Panel's {@code ContentViewCore}.
|
| - */
|
| - @Override
|
| - public ContentViewCore getSearchContentViewCore() {
|
| - return mSearchContentViewCore;
|
| - }
|
| -
|
| - /**
|
| - * Sets the {@code ContextualSearchContentViewDelegate} associated with the Content View.
|
| - * @param delegate
|
| - */
|
| - public void setSearchContentViewDelegate(ContextualSearchContentViewDelegate delegate) {
|
| - mSearchContentViewDelegate = delegate;
|
| - }
|
| -
|
| - /**
|
| - * Removes the last resolved search URL from the Chrome history.
|
| - */
|
| - private void removeLastSearchVisit() {
|
| - if (mSearchRequest != null) {
|
| - nativeRemoveLastSearchVisit(mNativeContextualSearchManagerPtr,
|
| - mSearchRequest.getSearchUrl(), mLoadedSearchUrlTimeMs);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Called when the Search content view navigates to a contextual search request URL.
|
| - * This navigation could be for a prefetch when the panel is still closed, or
|
| - * a load of a user-visible search result.
|
| - * @param isFailure Whether the navigation failed.
|
| - */
|
| - private void onContextualSearchRequestNavigation(boolean isFailure) {
|
| - if (mSearchRequest == null) return;
|
| -
|
| - if (mSearchRequest.isUsingLowPriority()) {
|
| - ContextualSearchUma.logLowPrioritySearchRequestOutcome(isFailure);
|
| - } else {
|
| - ContextualSearchUma.logNormalPrioritySearchRequestOutcome(isFailure);
|
| - if (mSearchRequest.getHasFailed()) {
|
| - ContextualSearchUma.logFallbackSearchRequestOutcome(isFailure);
|
| - }
|
| - }
|
| -
|
| - if (isFailure && mSearchRequest.isUsingLowPriority()) {
|
| - // We're navigating to an error page, so we want to stop and retry.
|
| - // Stop loading the page that displays the error to the user.
|
| - if (mSearchContentViewCore != null) {
|
| - // When running tests the Content View might not exist.
|
| - mSearchContentViewCore.getWebContents().stop();
|
| - }
|
| - mSearchRequest.setHasFailed();
|
| - mSearchRequest.setNormalPriority();
|
| - // If the content view is showing, load at normal priority now.
|
| - if (mIsSearchContentViewShowing) {
|
| - loadSearchUrl();
|
| - } else {
|
| - mDidLoadResolvedSearchRequest = false;
|
| - }
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void logPromoOutcome() {
|
| - ContextualSearchUma.logPromoOutcome(mWasActivatedByTap);
|
| - mDidLogPromoOutcome = true;
|
| - }
|
| -
|
| - /**
|
| - * Called when the Search Content view has finished loading to record how long it takes the SERP
|
| - * to load after opening the panel.
|
| - */
|
| - private void onSearchResultsLoaded() {
|
| - if (mSearchRequest == null) return;
|
| -
|
| - mSearchPanelDelegate.onSearchResultsLoaded(mSearchRequest.wasPrefetch());
|
| - }
|
| -
|
| - /**
|
| - * Creates a new Content View Core to display search results, if needed.
|
| - */
|
| - private void createNewSearchContentViewCoreIfNeeded() {
|
| - if (mSearchContentViewCore == null) {
|
| - mNetworkCommunicator.createNewSearchContentView();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void loadUrl(String url) {
|
| - createNewSearchContentViewCoreIfNeeded();
|
| - if (mSearchContentViewCore != null && mSearchContentViewCore.getWebContents() != null) {
|
| - mDidLoadAnyUrl = true;
|
| - mSearchContentViewCore.getWebContents().getNavigationController().loadUrl(
|
| - new LoadUrlParams(url));
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void createNewSearchContentView() {
|
| - if (mSearchContentViewCore != null) {
|
| - mNetworkCommunicator.destroySearchContentView();
|
| - }
|
| -
|
| - mSearchContentViewCore = new ContentViewCore(mActivity);
|
| - ContentView cv = new ContentView(mActivity, mSearchContentViewCore);
|
| - // Creates an initially hidden WebContents which gets shown when the panel is opened.
|
| - mSearchContentViewCore.initialize(cv, cv,
|
| - WebContentsFactory.createWebContents(false, true), mWindowAndroid);
|
| -
|
| - // Transfers the ownership of the WebContents to the native ContextualSearchManager.
|
| - nativeSetWebContents(mNativeContextualSearchManagerPtr, mSearchContentViewCore,
|
| - mWebContentsDelegate);
|
| -
|
| - mSearchWebContentsObserver =
|
| - new WebContentsObserver(mSearchContentViewCore.getWebContents()) {
|
| - @Override
|
| - public void didStartLoading(String url) {
|
| - mDidPromoteSearchNavigation = false;
|
| - }
|
| -
|
| - @Override
|
| - public void didStartProvisionalLoadForFrame(long frameId, long parentFrameId,
|
| - boolean isMainFrame, String validatedUrl, boolean isErrorPage,
|
| - boolean isIframeSrcdoc) {
|
| - if (isMainFrame) onExternalNavigation(validatedUrl);
|
| - }
|
| -
|
| - @Override
|
| - public void didNavigateMainFrame(String url, String baseUrl,
|
| - boolean isNavigationToDifferentPage, boolean isNavigationInPage,
|
| - int httpResultCode) {
|
| - mNetworkCommunicator.handleDidNavigateMainFrame(url, httpResultCode);
|
| - }
|
| -
|
| - @Override
|
| - public void didFinishLoad(long frameId, String validatedUrl,
|
| - boolean isMainFrame) {
|
| - onSearchResultsLoaded();
|
| -
|
| - // Any time we place a page in a ContentViewCore, clear history if needed.
|
| - // This prevents error URLs from appearing in the Tab's history stack.
|
| - // Also please note that clearHistory() will not
|
| - // clear the current entry (search results page in this case),
|
| - // and it will not work properly if there are pending navigations.
|
| - // That's why we need to clear the history here, after the navigation
|
| - // is completed.
|
| - boolean shouldClearHistory =
|
| - mSearchRequest != null && mSearchRequest.getHasFailed();
|
| - if (shouldClearHistory && mSearchContentViewCore != null) {
|
| - mSearchContentViewCore.getWebContents().getNavigationController()
|
| - .clearHistory();
|
| - }
|
| - }
|
| - };
|
| -
|
| - mSearchContentViewDelegate.setContextualSearchContentViewCore(mSearchContentViewCore);
|
| - nativeSetInterceptNavigationDelegate(mNativeContextualSearchManagerPtr,
|
| - new InterceptNavigationDelegateImpl(), mSearchContentViewCore.getWebContents());
|
| - }
|
| -
|
| - @Override
|
| - public void handleDidNavigateMainFrame(String url, int httpResultCode) {
|
| - if (shouldPromoteSearchNavigation()) {
|
| - onExternalNavigation(url);
|
| - } else {
|
| - // Could be just prefetching, check if that failed.
|
| - boolean isFailure = isHttpFailureCode(httpResultCode);
|
| - onContextualSearchRequestNavigation(isFailure);
|
| - }
|
| - mDidLoadAnyUrl = false;
|
| - }
|
| -
|
| - /**
|
| - * @return Whether the given HTTP result code represents a failure or not.
|
| - */
|
| - private boolean isHttpFailureCode(int httpResultCode) {
|
| - return httpResultCode <= 0 || httpResultCode >= 400;
|
| - }
|
| -
|
| - /**
|
| - * @return whether a navigation in the search content view should promote to a separate tab.
|
| - */
|
| - private boolean shouldPromoteSearchNavigation() {
|
| - // A navigation can be due to us loading a URL, or a touch in the search content view.
|
| - // Require a touch, but no recent loading, in order to promote to a separate tab.
|
| - // Note that tapping the opt-in button requires checking for recent loading.
|
| - return mSearchPanelDelegate.didTouchSearchContentView() && !mDidLoadAnyUrl;
|
| - }
|
| -
|
| - /**
|
| - * Called to check if an external navigation is being done and take the appropriate action:
|
| - * Auto-promotes the panel into a separate tab if that's not already being done.
|
| - * @param url The URL we are navigating to.
|
| - */
|
| - private void onExternalNavigation(String url) {
|
| - if (!mDidPromoteSearchNavigation
|
| - && !BLACKLISTED_URL.equals(url)
|
| - && !url.startsWith(INTENT_URL_PREFIX)
|
| - && shouldPromoteSearchNavigation()) {
|
| - // Do not promote to a regular tab if we're loading our Resolved Search
|
| - // URL, otherwise we'll promote it when prefetching the Serp.
|
| - // Don't promote URLs when they are navigating to an intent - this is
|
| - // handled by the InterceptNavigationDelegate which uses a faster
|
| - // maximizing animation.
|
| - mDidPromoteSearchNavigation = true;
|
| - mSearchPanelDelegate.maximizePanelThenPromoteToTab(StateChangeReason.SERP_NAVIGATION);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void destroySearchContentView() {
|
| - if (mSearchContentViewCore != null && mSearchContentViewDelegate != null) {
|
| - nativeDestroyWebContents(mNativeContextualSearchManagerPtr);
|
| - mSearchContentViewDelegate.releaseContextualSearchContentViewCore();
|
| - mSearchContentViewCore.destroy();
|
| - mSearchContentViewCore = null;
|
| - if (mSearchWebContentsObserver != null) {
|
| - mSearchWebContentsObserver.destroy();
|
| - mSearchWebContentsObserver = null;
|
| - }
|
| - }
|
| -
|
| - // This should be called last here. The setSearchContentViewVisibility method
|
| - // will change the visibility the SearchContentView but also set the value of the
|
| - // internal property mIsSearchContentViewShowing. If we call this after deleting
|
| - // the SearchContentView, it will be faster, because only the internal property
|
| - // will be changed, since there will be no need to change the visibility of the
|
| - // SearchContentView.
|
| - setSearchContentViewVisibility(false);
|
| - }
|
| -
|
| - @Override
|
| - public void openResolvedSearchUrlInNewTab() {
|
| - if (mSearchRequest != null && mSearchRequest.getSearchUrl() != null) {
|
| - openUrlInNewTab(mSearchRequest.getSearchUrl());
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Convenience method for opening a specific |url| in a new Tab.
|
| - */
|
| - private void openUrlInNewTab(String url) {
|
| - TabModelSelector tabModelSelector = mActivity.getTabModelSelector();
|
| - tabModelSelector.openNewTab(
|
| - new LoadUrlParams(url),
|
| - TabLaunchType.FROM_MENU_OR_OVERVIEW,
|
| - tabModelSelector.getCurrentTab(),
|
| - tabModelSelector.isIncognitoSelected());
|
| - }
|
| -
|
| - @Override
|
| - public boolean isRunningInCompatibilityMode() {
|
| - return DeviceClassManager.isAccessibilityModeEnabled(mActivity)
|
| - || SysUtils.isLowEndDevice();
|
| - }
|
| -
|
| - @Override
|
| - public void promoteToTab(boolean shouldFocusOmnibox) {
|
| - mIsPromotingToTab = true;
|
| - // If the request object is null that means that a Contextual Search has just started
|
| - // and the Search Term Resolution response hasn't arrived yet. In this case, promoting
|
| - // the Panel to a Tab will result in creating a new tab with URL about:blank. To prevent
|
| - // this problem, we are ignoring tap gestures in the Search Bar if we don't know what
|
| - // to search for.
|
| - if (mSearchRequest != null
|
| - && mSearchContentViewCore != null
|
| - && mSearchContentViewCore.getWebContents() != null) {
|
| - nativeReleaseWebContents(mNativeContextualSearchManagerPtr);
|
| - mSearchContentViewDelegate.releaseContextualSearchContentViewCore();
|
| - if (!mTabPromotionDelegate.createContextualSearchTab(mSearchContentViewCore)) {
|
| - nativeDestroyWebContentsFromContentViewCore(mNativeContextualSearchManagerPtr,
|
| - mSearchContentViewCore);
|
| - mSearchContentViewCore.destroy();
|
| - }
|
| - if (mSearchWebContentsObserver != null) {
|
| - mSearchWebContentsObserver.destroy();
|
| - mSearchWebContentsObserver = null;
|
| - }
|
| - mSearchContentViewCore = null;
|
| - mIsSearchContentViewShowing = false;
|
| - mSearchRequest = null;
|
| -
|
| - // NOTE(pedrosimonetti): The Panel should be closed after being promoted to a Tab
|
| - // to prevent Chrome-Android from animating the creation of the new Tab.
|
| - mSearchPanelDelegate.closePanel(StateChangeReason.TAB_PROMOTION, false);
|
| -
|
| - // Focus the Omnibox.
|
| - if (shouldFocusOmnibox) {
|
| - new Handler().post(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - View urlBarView = mActivity.findViewById(R.id.url_bar);
|
| - urlBarView.requestFocus();
|
| - }
|
| - });
|
| - }
|
| - }
|
| - mIsPromotingToTab = false;
|
| - }
|
| -
|
| - @Override
|
| - public void resetSearchContentViewScroll() {
|
| - if (mSearchContentViewCore != null) {
|
| - mSearchContentViewCore.scrollTo(0, 0);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public float getSearchContentViewVerticalScroll() {
|
| - return mSearchContentViewCore != null
|
| - ? mSearchContentViewCore.computeVerticalScrollOffset() : -1.f;
|
| - }
|
| -
|
| - @Override
|
| - public void setSearchContentViewVisibility(boolean isVisible) {
|
| - if (mIsSearchContentViewShowing == isVisible) return;
|
| -
|
| - mIsSearchContentViewShowing = isVisible;
|
| - if (isVisible) {
|
| - mWereSearchResultsSeen = true;
|
| - // If there's no current request, then either a search term resolution
|
| - // is in progress or we should do a verbatim search now.
|
| - if (mSearchRequest == null
|
| - && mPolicy.shouldCreateVerbatimRequest(mSelectionController,
|
| - mNetworkCommunicator.getBasePageUrl())) {
|
| - mSearchRequest = new ContextualSearchRequest(
|
| - mSelectionController.getSelectedText());
|
| - mDidLoadResolvedSearchRequest = false;
|
| - }
|
| - if (mSearchRequest != null && !mDidLoadResolvedSearchRequest) {
|
| - mSearchRequest.setNormalPriority();
|
| - loadSearchUrl();
|
| - }
|
| - // The CVC is created with the search request, but if none was made we'll need
|
| - // one in order to display an empty panel.
|
| - createNewSearchContentViewCoreIfNeeded();
|
| - if (mSearchContentViewCore != null) mSearchContentViewCore.onShow();
|
| - mSearchPanelDelegate.setWasSearchContentViewSeen();
|
| - mPolicy.updateCountersForOpen();
|
| - } else {
|
| - if (mSearchContentViewCore != null) mSearchContentViewCore.onHide();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void preserveBasePageSelectionOnNextLossOfFocus() {
|
| - ContentViewCore basePageContentView = getBaseContentView();
|
| - if (basePageContentView != null) {
|
| - basePageContentView.preserveSelectionOnNextLossOfFocus();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void dismissContextualSearchBar() {
|
| - hideContextualSearch(StateChangeReason.UNKNOWN);
|
| - }
|
| -
|
| - // Used to intercept intent navigations.
|
| - // TODO(jeremycho): Consider creating a Tab with the Panel's ContentViewCore,
|
| - // which would also handle functionality like long-press-to-paste.
|
| - private class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate {
|
| - final ExternalNavigationHandler mExternalNavHandler = new ExternalNavigationHandler(
|
| - mActivity);
|
| - @Override
|
| - public boolean shouldIgnoreNavigation(NavigationParams navigationParams) {
|
| - mTabRedirectHandler.updateNewUrlLoading(navigationParams.pageTransitionType,
|
| - navigationParams.isRedirect,
|
| - navigationParams.hasUserGesture || navigationParams.hasUserGestureCarryover,
|
| - mActivity.getLastUserInteractionTime(), TabRedirectHandler.INVALID_ENTRY_INDEX);
|
| -
|
| - ExternalNavigationParams params = new ExternalNavigationParams.Builder(
|
| - navigationParams.url, false, navigationParams.referrer,
|
| - navigationParams.pageTransitionType, navigationParams.isRedirect)
|
| - .setApplicationMustBeInForeground(true)
|
| - .setRedirectHandler(mTabRedirectHandler)
|
| - .setIsMainFrame(navigationParams.isMainFrame)
|
| - .build();
|
| - if (mExternalNavHandler.shouldOverrideUrlLoading(params)
|
| - != OverrideUrlLoadingResult.NO_OVERRIDE) {
|
| - mSearchPanelDelegate.maximizePanelThenPromoteToTab(
|
| - StateChangeReason.TAB_PROMOTION,
|
| - INTERCEPT_NAVIGATION_PROMOTION_ANIMATION_DURATION_MS);
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - // --------------------------------------------------------------------------------------------
|
| - // ContextualSearchClient -- interface used by ContentViewCore.
|
| - // --------------------------------------------------------------------------------------------
|
| -
|
| - @Override
|
| - public void onSelectionChanged(String selection) {
|
| - mSelectionController.handleSelectionChanged(selection);
|
| - updateTopControlsState(TopControlsState.BOTH, true);
|
| - }
|
| -
|
| - @Override
|
| - public void onSelectionEvent(int eventType, float posXPix, float posYPix) {
|
| - mSelectionController.handleSelectionEvent(eventType, posXPix, posYPix);
|
| - }
|
| -
|
| - @Override
|
| - public void showUnhandledTapUIIfNeeded(final int x, final int y) {
|
| - mDidBasePageLoadJustStart = false;
|
| - mSelectionController.handleShowUnhandledTapUIIfNeeded(x, y);
|
| - }
|
| -
|
| - // --------------------------------------------------------------------------------------------
|
| - // Selection
|
| - // --------------------------------------------------------------------------------------------
|
| -
|
| - /**
|
| - * Returns a new {@code GestureStateListener} that will listen for events in the Base Page.
|
| - * This listener will handle all Contextual Search-related interactions that go through the
|
| - * listener.
|
| - */
|
| - public GestureStateListener getGestureStateListener() {
|
| - return mSelectionController.getGestureStateListener();
|
| - }
|
| -
|
| - @Override
|
| - public void handleScroll() {
|
| - hideContextualSearch(StateChangeReason.BASE_PAGE_SCROLL);
|
| - }
|
| -
|
| - @Override
|
| - public void handleInvalidTap() {
|
| - hideContextualSearch(StateChangeReason.BASE_PAGE_TAP);
|
| - }
|
| -
|
| - @Override
|
| - public void handleValidTap() {
|
| - if (isTapSupported()) {
|
| - // Here we are starting a new Contextual Search with a Tap gesture, therefore
|
| - // we need to clear to properly reflect that a search just started and we don't
|
| - // have the resolved search term yet.
|
| - mSearchRequest = null;
|
| -
|
| - // Let the policy know that a tap gesture has been received.
|
| - mPolicy.registerTap();
|
| -
|
| - ContentViewCore baseContentView = getBaseContentView();
|
| - if (baseContentView != null) baseContentView.getWebContents().selectWordAroundCaret();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void handleSelection(String selection, SelectionType type, float x, float y) {
|
| - if (!selection.isEmpty()) {
|
| - boolean isSelectionValid = isValidSelection(selection);
|
| -
|
| - StateChangeReason stateChangeReason = type == SelectionType.TAP
|
| - ? StateChangeReason.TEXT_SELECT_TAP : StateChangeReason.TEXT_SELECT_LONG_PRESS;
|
| - ContextualSearchUma.logSelectionIsValid(isSelectionValid);
|
| -
|
| - if (isSelectionValid) {
|
| - mSearchPanelDelegate.updateBasePageSelectionYPx(y);
|
| - showContextualSearch(stateChangeReason);
|
| - } else {
|
| - hideContextualSearch(stateChangeReason);
|
| - }
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void handleSelectionDismissal() {
|
| - if (mSearchPanelDelegate.isShowing() && !mIsPromotingToTab) {
|
| - hideContextualSearch(StateChangeReason.CLEARED_SELECTION);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void handleSelectionModification(String selection, float x, float y) {
|
| - if (mSearchPanelDelegate.isShowing()) {
|
| - getContextualSearchControl().setCentralText(selection);
|
| - }
|
| - }
|
| -
|
| - // --------------------------------------------------------------------------------------------
|
| - // Native calls
|
| - // --------------------------------------------------------------------------------------------
|
| -
|
| - private native long nativeInit();
|
| - private native void nativeDestroy(long nativeContextualSearchManager);
|
| - private native void nativeStartSearchTermResolutionRequest(long nativeContextualSearchManager,
|
| - String selection, boolean useResolvedSearchTerm, ContentViewCore baseContentViewCore,
|
| - boolean maySendBasePageUrl);
|
| - private native void nativeGatherSurroundingText(long nativeContextualSearchManager,
|
| - String selection, boolean useResolvedSearchTerm, ContentViewCore baseContentViewCore,
|
| - boolean maySendBasePageUrl);
|
| - private native void nativeRemoveLastSearchVisit(
|
| - long nativeContextualSearchManager, String searchUrl, long searchUrlTimeMs);
|
| - private native void nativeSetWebContents(long nativeContextualSearchManager,
|
| - ContentViewCore searchContentViewCore, WebContentsDelegateAndroid delegate);
|
| - private native void nativeDestroyWebContents(long nativeContextualSearchManager);
|
| - private native void nativeReleaseWebContents(long nativeContextualSearchManager);
|
| - private native void nativeDestroyWebContentsFromContentViewCore(
|
| - long nativeContextualSearchManager, ContentViewCore contentViewCore);
|
| - private native void nativeSetInterceptNavigationDelegate(long nativeContextualSearchManager,
|
| - InterceptNavigationDelegate delegate, WebContents webContents);
|
| -}
|
|
|