| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b334ae1fdc3b46816e3d742eee67b570f849a788
|
| --- /dev/null
|
| +++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
|
| @@ -0,0 +1,192 @@
|
| +// 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 org.chromium.base.CalledByNative;
|
| +import org.chromium.chrome.browser.CompositorChromeActivity;
|
| +import org.chromium.chrome.browser.EmptyTabObserver;
|
| +import org.chromium.chrome.browser.Tab;
|
| +import org.chromium.chrome.browser.preferences.PrefServiceBridge;
|
| +import org.chromium.chrome.browser.profiles.Profile;
|
| +import org.chromium.chrome.browser.search_engines.TemplateUrlService;
|
| +import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrlServiceObserver;
|
| +import org.chromium.content.browser.ContentViewCore;
|
| +import org.chromium.content_public.browser.GestureStateListener;
|
| +
|
| +/**
|
| + * Manages the activation and gesture listeners for ContextualSearch on a given tab.
|
| + */
|
| +public class ContextualSearchTabHelper extends EmptyTabObserver {
|
| + /**
|
| + * Notification handler for Contextual Search events.
|
| + */
|
| + private final TemplateUrlServiceObserver mTemplateUrlObserver =
|
| + new TemplateUrlServiceObserver() {
|
| + @Override
|
| + public void onTemplateURLServiceChanged() {
|
| + onContextualSearchPrefChanged();
|
| + }
|
| + };
|
| +
|
| + /**
|
| + * The current ContentViewCore for the Tab which this helper is monitoring.
|
| + */
|
| + private ContentViewCore mBaseContentViewCore;
|
| +
|
| + /**
|
| + * The GestureListener used for handling events from the current ContentViewCore.
|
| + */
|
| + private GestureStateListener mGestureStateListener;
|
| +
|
| + private long mNativeHelper = 0;
|
| +
|
| + /**
|
| + * Creates a contextual search tab helper for the given tab.
|
| + * @param tab The tab whose contextual search actions will be handled by this helper.
|
| + */
|
| + public static void createForTab(Tab tab) {
|
| + new ContextualSearchTabHelper(tab);
|
| + }
|
| +
|
| + private ContextualSearchTabHelper(Tab tab) {
|
| + tab.addObserver(this);
|
| + }
|
| +
|
| + @Override
|
| + public void onPageLoadStarted(Tab tab) {
|
| + if (tab.getContentViewCore() == null) {
|
| + // Nothing to do yet.
|
| + return;
|
| + }
|
| +
|
| + mBaseContentViewCore = tab.getContentViewCore();
|
| + // Add Contextual Search here in case it couldn't get added in onContentChanged() due to
|
| + // being too early in initialization of Chrome (ContextualSearchManager being null).
|
| + setContextualSearchHooks(mBaseContentViewCore);
|
| + }
|
| +
|
| + @Override
|
| + public void onPageLoadFinished(Tab tab) {
|
| + // Native initialization happens after a page loads to ensure profile is initialized.
|
| + if (mNativeHelper == 0) {
|
| + mNativeHelper = nativeInit(tab.getProfile());
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onContentChanged(Tab tab) {
|
| + updateHooksForNewContentViewCore(tab);
|
| + }
|
| +
|
| + @Override
|
| + public void onWebContentsSwapped(Tab tab, boolean didStartLoad, boolean didFinishLoad) {
|
| + updateHooksForNewContentViewCore(tab);
|
| + }
|
| +
|
| + @Override
|
| + public void onDestroyed(Tab tab) {
|
| + if (mNativeHelper != 0) {
|
| + nativeDestroy(mNativeHelper);
|
| + mNativeHelper = 0;
|
| + }
|
| + removeContextualSearchHooks(mBaseContentViewCore);
|
| + mBaseContentViewCore = null;
|
| + }
|
| +
|
| + /**
|
| + * Should be called whenever the Tab's ContentViewCore changes. Removes hooks from the
|
| + * existing ContentViewCore, if necessary and then adds hooks for the new ContentViewCore.
|
| + * @param tab
|
| + */
|
| + private void updateHooksForNewContentViewCore(Tab tab) {
|
| + removeContextualSearchHooks(mBaseContentViewCore);
|
| + mBaseContentViewCore = tab.getContentViewCore();
|
| + setContextualSearchHooks(mBaseContentViewCore);
|
| + }
|
| +
|
| + /**
|
| + * Sets up the Contextual Search hooks, adding or removing them depending on whether it is
|
| + * currently active.
|
| + * @param cvc The content view core to attach the gesture state listener to.
|
| + */
|
| + private void setContextualSearchHooks(ContentViewCore cvc) {
|
| + if (cvc == null) return;
|
| +
|
| + if (isContextualSearchActive(cvc)) {
|
| + addContextualSearchHooks(cvc);
|
| + } else {
|
| + removeContextualSearchHooks(cvc);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Adds Contextual Search hooks for its client and listener to the given content view core.
|
| + * @param cvc The content view core to attach the gesture state listener to.
|
| + */
|
| + private void addContextualSearchHooks(ContentViewCore cvc) {
|
| + if (ContextualSearchFieldTrial.isEnabled(cvc.getContext().getApplicationContext())) {
|
| + ContextualSearchUma.logPreferenceState(
|
| + ContextualSearchPolicy.getInstance(cvc.getContext()).getPromoTapsRemaining());
|
| + }
|
| + if (mGestureStateListener == null) {
|
| + mGestureStateListener = getContextualSearchManager(cvc).getGestureStateListener();
|
| + cvc.addGestureStateListener(mGestureStateListener);
|
| + cvc.setContextualSearchClient(getContextualSearchManager(cvc));
|
| + TemplateUrlService.getInstance().addObserver(mTemplateUrlObserver);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Removes Contextual Search hooks for its client and listener from the given content view core.
|
| + * @param cvc The content view core to detach the gesture state listener from.
|
| + */
|
| + private void removeContextualSearchHooks(ContentViewCore cvc) {
|
| + if (cvc == null) return;
|
| +
|
| + if (ContextualSearchFieldTrial.isEnabled(cvc.getContext().getApplicationContext())) {
|
| + ContextualSearchUma.logPreferenceState(
|
| + ContextualSearchPolicy.getInstance(cvc.getContext()).getPromoTapsRemaining());
|
| + }
|
| + if (mGestureStateListener != null) {
|
| + cvc.removeGestureStateListener(mGestureStateListener);
|
| + mGestureStateListener = null;
|
| + cvc.setContextualSearchClient(null);
|
| + TemplateUrlService.getInstance().removeObserver(mTemplateUrlObserver);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @return whether Contextual Search is enabled and active in this tab.
|
| + */
|
| + private static boolean isContextualSearchActive(ContentViewCore cvc) {
|
| + return !cvc.getWebContents().isIncognito() && getContextualSearchManager(cvc) != null
|
| + && !PrefServiceBridge.getInstance().isContextualSearchDisabled()
|
| + && TemplateUrlService.getInstance().isDefaultSearchEngineGoogle()
|
| + // Svelte and Accessibility devices are incompatible with the first-run flow and
|
| + // Talkback has poor interaction with tap to search (see http://crbug.com/399708 and
|
| + // http://crbug.com/396934).
|
| + // TODO(jeremycho): Handle these cases.
|
| + && !getContextualSearchManager(cvc).isRunningInCompatibilityMode();
|
| + }
|
| +
|
| + /**
|
| + * @return the Contextual Search manager.
|
| + */
|
| + private static ContextualSearchManager getContextualSearchManager(ContentViewCore cvc) {
|
| + // TODO(yfriedman): Decouple this from the activity.
|
| + if (cvc.getContext() instanceof CompositorChromeActivity) {
|
| + return ((CompositorChromeActivity) cvc.getContext()).getContextualSearchManager();
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + @CalledByNative
|
| + private void onContextualSearchPrefChanged() {
|
| + setContextualSearchHooks(mBaseContentViewCore);
|
| + }
|
| +
|
| + private native long nativeInit(Profile profile);
|
| + private native void nativeDestroy(long nativeContextualSearchTabHelper);
|
| +}
|
|
|