Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java

Issue 1354763003: [Contextual Search] Trigger the translation one-box. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased with Pedro's new test infrastructure, updated these instrumentation tests to use that. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.contextualsearch; 5 package org.chromium.chrome.browser.contextualsearch;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.content.Context;
8 import android.view.View; 9 import android.view.View;
9 import android.view.ViewGroup; 10 import android.view.ViewGroup;
10 import android.view.ViewTreeObserver; 11 import android.view.ViewTreeObserver;
11 import android.view.ViewTreeObserver.OnGlobalFocusChangeListener; 12 import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
12 13
13 import org.chromium.base.ActivityState; 14 import org.chromium.base.ActivityState;
14 import org.chromium.base.ApplicationStatus; 15 import org.chromium.base.ApplicationStatus;
15 import org.chromium.base.ApplicationStatus.ActivityStateListener; 16 import org.chromium.base.ApplicationStatus.ActivityStateListener;
16 import org.chromium.base.SysUtils; 17 import org.chromium.base.SysUtils;
17 import org.chromium.base.VisibleForTesting; 18 import org.chromium.base.VisibleForTesting;
(...skipping 23 matching lines...) Expand all
41 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; 42 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager;
42 import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver; 43 import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver;
43 import org.chromium.components.navigation_interception.NavigationParams; 44 import org.chromium.components.navigation_interception.NavigationParams;
44 import org.chromium.content.browser.ContentViewCore; 45 import org.chromium.content.browser.ContentViewCore;
45 import org.chromium.content.browser.ContextualSearchClient; 46 import org.chromium.content.browser.ContextualSearchClient;
46 import org.chromium.content_public.browser.GestureStateListener; 47 import org.chromium.content_public.browser.GestureStateListener;
47 import org.chromium.content_public.browser.LoadUrlParams; 48 import org.chromium.content_public.browser.LoadUrlParams;
48 import org.chromium.content_public.browser.NavigationEntry; 49 import org.chromium.content_public.browser.NavigationEntry;
49 import org.chromium.content_public.browser.WebContentsObserver; 50 import org.chromium.content_public.browser.WebContentsObserver;
50 import org.chromium.content_public.common.TopControlsState; 51 import org.chromium.content_public.common.TopControlsState;
52 import org.chromium.ui.UiUtils;
51 import org.chromium.ui.base.WindowAndroid; 53 import org.chromium.ui.base.WindowAndroid;
52 54
53 import java.net.MalformedURLException; 55 import java.net.MalformedURLException;
54 import java.net.URL; 56 import java.net.URL;
57 import java.util.ArrayList;
58 import java.util.LinkedHashSet;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Set;
55 62
56 import javax.annotation.Nullable; 63 import javax.annotation.Nullable;
57 64
58 65
59 /** 66 /**
60 * Manager for the Contextual Search feature. 67 * Manager for the Contextual Search feature.
61 * This class keeps track of the status of Contextual Search and coordinates the control 68 * This class keeps track of the status of Contextual Search and coordinates the control
62 * with the layout. 69 * with the layout.
63 */ 70 */
64 public class ContextualSearchManager extends ContextualSearchObservable 71 public class ContextualSearchManager extends ContextualSearchObservable
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 114
108 /** 115 /**
109 * This boolean is used for loading content after a long-press when content is not immediately 116 * This boolean is used for loading content after a long-press when content is not immediately
110 * loaded. 117 * loaded.
111 */ 118 */
112 private boolean mShouldLoadDelayedSearch; 119 private boolean mShouldLoadDelayedSearch;
113 120
114 private boolean mIsShowingPromo; 121 private boolean mIsShowingPromo;
115 private boolean mDidLogPromoOutcome; 122 private boolean mDidLogPromoOutcome;
116 123
124 // Cached target languages for translation;
125 private List<String> mTargetLanguages;
126
117 /** 127 /**
118 * Whether contextual search manager is currently promoting a tab. We should be ignoring hide 128 * Whether contextual search manager is currently promoting a tab. We should be ignoring hide
119 * requests when mIsPromotingTab is set to true. 129 * requests when mIsPromotingTab is set to true.
120 */ 130 */
121 private boolean mIsPromotingToTab; 131 private boolean mIsPromotingToTab;
122 132
123 private ContextualSearchNetworkCommunicator mNetworkCommunicator; 133 private ContextualSearchNetworkCommunicator mNetworkCommunicator;
124 private ContextualSearchPanel mSearchPanel; 134 private ContextualSearchPanel mSearchPanel;
125 135
126 // TODO(pedrosimonetti): also store selected text, surroundings, url, boundi ng rect of selected 136 // TODO(pedrosimonetti): also store selected text, surroundings, url, boundi ng rect of selected
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 293
284 /** 294 /**
285 * @return The {@link ContextualSearchPanel}, for testing purposes only. 295 * @return The {@link ContextualSearchPanel}, for testing purposes only.
286 */ 296 */
287 @VisibleForTesting 297 @VisibleForTesting
288 public ContextualSearchPanel getContextualSearchPanel() { 298 public ContextualSearchPanel getContextualSearchPanel() {
289 return mSearchPanel; 299 return mSearchPanel;
290 } 300 }
291 301
292 /** 302 /**
293 * Sets the selection controller for testing purposes. 303 * @return The selection controller, for testing purposes.
294 */ 304 */
295 @VisibleForTesting 305 @VisibleForTesting
296 ContextualSearchSelectionController getSelectionController() { 306 ContextualSearchSelectionController getSelectionController() {
297 return mSelectionController; 307 return mSelectionController;
298 } 308 }
299 309
310 /**
311 * @return The current search request, or {@code null} if there is none, for testing.
312 */
313 @VisibleForTesting
314 ContextualSearchRequest getRequest() {
315 return mSearchRequest;
316 }
317
300 @VisibleForTesting 318 @VisibleForTesting
301 boolean isSearchPanelShowing() { 319 boolean isSearchPanelShowing() {
302 return mSearchPanel.isShowing(); 320 return mSearchPanel.isShowing();
303 } 321 }
304 322
305 /** 323 /**
306 * @return Whether the Search Panel is opened. That is, whether it is EXPAND ED or MAXIMIZED. 324 * @return Whether the Search Panel is opened. That is, whether it is EXPAND ED or MAXIMIZED.
307 */ 325 */
308 public boolean isSearchPanelOpened() { 326 public boolean isSearchPanelOpened() {
309 PanelState state = mSearchPanel.getPanelState(); 327 PanelState state = mSearchPanel.getPanelState();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 if (isTap) { 487 if (isTap) {
470 // If the user action was not a long-press, immediately start loadin g content. 488 // If the user action was not a long-press, immediately start loadin g content.
471 mShouldLoadDelayedSearch = false; 489 mShouldLoadDelayedSearch = false;
472 } 490 }
473 491
474 if (isTap && mPolicy.shouldPreviousTapResolve( 492 if (isTap && mPolicy.shouldPreviousTapResolve(
475 mNetworkCommunicator.getBasePageUrl())) { 493 mNetworkCommunicator.getBasePageUrl())) {
476 mNetworkCommunicator.startSearchTermResolutionRequest( 494 mNetworkCommunicator.startSearchTermResolutionRequest(
477 mSelectionController.getSelectedText()); 495 mSelectionController.getSelectedText());
478 didRequestSurroundings = true; 496 didRequestSurroundings = true;
497 // Cache the target languages in case they are needed for translatio n.
498 if (mPolicy.isTranslationEnabled()) getTargetLanguages();
479 } else { 499 } else {
480 boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(isTap); 500 boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(isTap);
481 mSearchRequest = new ContextualSearchRequest(mSelectionController.ge tSelectedText(), 501 mSearchRequest = new ContextualSearchRequest(mSelectionController.ge tSelectedText(),
482 null, shouldPrefetch); 502 null, shouldPrefetch);
503 // TODO(donnd): figure out a way to do translation on long-press sel ections.
483 mDidStartLoadingResolvedSearchRequest = false; 504 mDidStartLoadingResolvedSearchRequest = false;
484 mSearchPanel.displaySearchTerm(mSelectionController.getSelectedText( )); 505 mSearchPanel.displaySearchTerm(mSelectionController.getSelectedText( ));
485 if (shouldPrefetch) loadSearchUrl(); 506 if (shouldPrefetch) loadSearchUrl();
486 } 507 }
487 508
488 if (!didRequestSurroundings) { 509 if (!didRequestSurroundings) {
489 // Gather surrounding text for Icing integration, which will make th e selection and 510 // Gather surrounding text for Icing integration, which will make th e selection and
490 // a shorter version of the surroundings available for Conversationa l Search. 511 // a shorter version of the surroundings available for Conversationa l Search.
491 // Although the surroundings are extracted, they will not be sent to the server as 512 // Although the surroundings are extracted, they will not be sent to the server as
492 // part of search term resolution, just sent to Icing which keeps th em local until 513 // part of search term resolution, just sent to Icing which keeps th em local until
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 * parameters should be ignored. 689 * parameters should be ignored.
669 * @param responseCode The HTTP response code. If the code is not OK, the q uery 690 * @param responseCode The HTTP response code. If the code is not OK, the q uery
670 * should be ignored. 691 * should be ignored.
671 * @param searchTerm The term to use in our subsequent search. 692 * @param searchTerm The term to use in our subsequent search.
672 * @param displayText The text to display in our UX. 693 * @param displayText The text to display in our UX.
673 * @param alternateTerm The alternate term to display on the results page. 694 * @param alternateTerm The alternate term to display on the results page.
674 * @param selectionStartAdjust A positive number of characters that the star t of the existing 695 * @param selectionStartAdjust A positive number of characters that the star t of the existing
675 * selection should be expanded by. 696 * selection should be expanded by.
676 * @param selectionEndAdjust A positive number of characters that the end of the existing 697 * @param selectionEndAdjust A positive number of characters that the end of the existing
677 * selection should be expanded by. 698 * selection should be expanded by.
699 * @param contextLanguage The language of the original search term, or an em pty string.
678 */ 700 */
679 @CalledByNative 701 @CalledByNative
680 public void onSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode, 702 public void onSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
681 final String searchTerm, final String displayText, final String alte rnateTerm, 703 final String searchTerm, final String displayText, final String alte rnateTerm,
682 boolean doPreventPreload, int selectionStartAdjust, int selectionEnd Adjust) { 704 boolean doPreventPreload, int selectionStartAdjust, int selectionEnd Adjust,
705 final String contextLanguage) {
683 mNetworkCommunicator.handleSearchTermResolutionResponse(isNetworkUnavail able, responseCode, 706 mNetworkCommunicator.handleSearchTermResolutionResponse(isNetworkUnavail able, responseCode,
684 searchTerm, displayText, alternateTerm, doPreventPreload, select ionStartAdjust, 707 searchTerm, displayText, alternateTerm, doPreventPreload, select ionStartAdjust,
685 selectionEndAdjust); 708 selectionEndAdjust, contextLanguage);
686 } 709 }
687 710
688 @Override 711 @Override
689 public void handleSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode, 712 public void handleSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
690 String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload, 713 String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload,
691 int selectionStartAdjust, int selectionEndAdjust) { 714 int selectionStartAdjust, int selectionEndAdjust, String contextLang uage) {
692 if (!mSearchPanel.isShowing()) return; 715 if (!mSearchPanel.isShowing()) return;
693 716
694 // Show an appropriate message for what to search for. 717 // Show an appropriate message for what to search for.
695 String message; 718 String message;
696 boolean doLiteralSearch = false; 719 boolean doLiteralSearch = false;
697 if (isNetworkUnavailable) { 720 if (isNetworkUnavailable) {
698 message = mActivity.getResources().getString( 721 message = mActivity.getResources().getString(
699 R.string.contextual_search_network_unavailable); 722 R.string.contextual_search_network_unavailable);
700 } else if (!isHttpFailureCode(responseCode)) { 723 } else if (!isHttpFailureCode(responseCode)) {
701 message = displayText; 724 message = displayText;
(...skipping 12 matching lines...) Expand all
714 if (doLiteralSearch) { 737 if (doLiteralSearch) {
715 searchTerm = mSelectionController.getSelectedText(); 738 searchTerm = mSelectionController.getSelectedText();
716 alternateTerm = null; 739 alternateTerm = null;
717 doPreventPreload = true; 740 doPreventPreload = true;
718 } 741 }
719 if (!searchTerm.isEmpty()) { 742 if (!searchTerm.isEmpty()) {
720 // TODO(donnd): Instead of preloading, we should prefetch (ie the UR L should not 743 // TODO(donnd): Instead of preloading, we should prefetch (ie the UR L should not
721 // appear in the user's history until the user views it). See crbug .com/406446. 744 // appear in the user's history until the user views it). See crbug .com/406446.
722 boolean shouldPreload = !doPreventPreload && mPolicy.shouldPrefetchS earchResult(true); 745 boolean shouldPreload = !doPreventPreload && mPolicy.shouldPrefetchS earchResult(true);
723 mSearchRequest = new ContextualSearchRequest(searchTerm, alternateTe rm, shouldPreload); 746 mSearchRequest = new ContextualSearchRequest(searchTerm, alternateTe rm, shouldPreload);
747 // Trigger translation, if enabled.
748 if (!contextLanguage.isEmpty() && mPolicy.isTranslationEnabled()) {
749 List<String> targetLanguages = getTargetLanguages();
750 if (mPolicy.needsTranslation(contextLanguage, targetLanguages)) {
751 mSearchRequest.forceTranslation(
752 contextLanguage, mPolicy.bestTargetLanguage(targetLa nguages));
753 }
754 }
724 mDidStartLoadingResolvedSearchRequest = false; 755 mDidStartLoadingResolvedSearchRequest = false;
725 if (mSearchPanel.isContentShowing()) { 756 if (mSearchPanel.isContentShowing()) {
726 mSearchRequest.setNormalPriority(); 757 mSearchRequest.setNormalPriority();
727 } 758 }
728 if (mSearchPanel.isContentShowing() || shouldPreload) { 759 if (mSearchPanel.isContentShowing() || shouldPreload) {
729 loadSearchUrl(); 760 loadSearchUrl();
730 } 761 }
731 mPolicy.logSearchTermResolutionDetails(searchTerm, 762 mPolicy.logSearchTermResolutionDetails(searchTerm,
732 mNetworkCommunicator.getBasePageUrl()); 763 mNetworkCommunicator.getBasePageUrl());
733 } 764 }
(...skipping 28 matching lines...) Expand all
762 * @return Whether a Tap gesture is currently supported. 793 * @return Whether a Tap gesture is currently supported.
763 */ 794 */
764 private boolean isTapSupported() { 795 private boolean isTapSupported() {
765 // Base page just started navigating away, so taps should be ignored. 796 // Base page just started navigating away, so taps should be ignored.
766 if (mDidBasePageLoadJustStart) return false; 797 if (mDidBasePageLoadJustStart) return false;
767 798
768 return mPolicy.isTapSupported(); 799 return mPolicy.isTapSupported();
769 } 800 }
770 801
771 // ========================================================================= =================== 802 // ========================================================================= ===================
803 // Translation support
804 // ========================================================================= ===================
805
806 /**
807 * Gets the list of target languages for the current user, with the first
808 * item in the list being the user's primary language.
809 * @return The {@link List} of languages the user understands with their pri mary language first.
810 */
811 private List<String> getTargetLanguages() {
812 // May be cached.
813 if (mTargetLanguages != null) return mTargetLanguages;
814
815 // Using LinkedHashSet keeps the entries both unique and ordered.
816 Set<String> uniqueLanguages = new LinkedHashSet<String>();
817
818 // The primary language always comes first.
819 uniqueLanguages.add(
820 trimLocaleToLanguage(nativeGetTargetLanguage(mNativeContextualSe archManagerPtr)));
821
822 // Next add languages the user knows how to type.
823 Context context = mActivity.getApplicationContext();
824 List<String> locales = context != null
825 ? new ArrayList<String>(UiUtils.getIMELocales(context))
826 : new ArrayList<String>();
827 for (int i = 0; i < locales.size(); i++) {
828 uniqueLanguages.add(trimLocaleToLanguage(locales.get(i)));
829 }
830
831 // Add the accept languages last, since they are a weaker hint than pres ence of a keyboard.
832 List<String> acceptLanguages = getAcceptLanguages();
833 for (int i = 0; i < acceptLanguages.size(); i++) {
834 uniqueLanguages.add(trimLocaleToLanguage(acceptLanguages.get(i)));
835 }
836 mTargetLanguages = new ArrayList<String>(uniqueLanguages);
837 return mTargetLanguages;
838 }
839
840 /**
841 * Gets the list of accept languages for this user.
842 * @return The {@link List} of languages the user understands or does not wa nt translated.
843 */
844 private List<String> getAcceptLanguages() {
845 String acceptLanguages = nativeGetAcceptLanguages(mNativeContextualSearc hManagerPtr);
846 List<String> result = new ArrayList<String>();
847 for (String language : acceptLanguages.split(",")) {
848 result.add(language);
849 }
850 return result;
851 }
852
853 /**
854 * @return The given locale as a language code.
855 */
856 private String trimLocaleToLanguage(String locale) {
857 // TODO(donnd): use getScript or getLanguageTag (both API 21), or some o ther standard way to
858 // strip the country, instead of hard-coding the two character language code.
859 // TODO(donnd): Shouldn't getLanguage() do this?
860 String trimmedLocale = locale.substring(0, 2);
861 return new Locale(trimmedLocale).getLanguage();
862 }
863
864 // ========================================================================= ===================
772 // OverlayContentDelegate 865 // OverlayContentDelegate
773 // ========================================================================= =================== 866 // ========================================================================= ===================
774 867
775 @Override 868 @Override
776 public OverlayContentDelegate getOverlayContentDelegate() { 869 public OverlayContentDelegate getOverlayContentDelegate() {
777 return new SearchOverlayContentDelegate(); 870 return new SearchOverlayContentDelegate();
778 } 871 }
779 872
780 /** 873 /**
781 * Implementation of OverlayContentDelegate. Made public for testing purpose s. 874 * Implementation of OverlayContentDelegate. Made public for testing purpose s.
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 // ------------------------------------------------------------------------- ------------------- 1280 // ------------------------------------------------------------------------- -------------------
1188 1281
1189 private native long nativeInit(); 1282 private native long nativeInit();
1190 private native void nativeDestroy(long nativeContextualSearchManager); 1283 private native void nativeDestroy(long nativeContextualSearchManager);
1191 private native void nativeStartSearchTermResolutionRequest(long nativeContex tualSearchManager, 1284 private native void nativeStartSearchTermResolutionRequest(long nativeContex tualSearchManager,
1192 String selection, boolean useResolvedSearchTerm, ContentViewCore bas eContentViewCore, 1285 String selection, boolean useResolvedSearchTerm, ContentViewCore bas eContentViewCore,
1193 boolean maySendBasePageUrl); 1286 boolean maySendBasePageUrl);
1194 private native void nativeGatherSurroundingText(long nativeContextualSearchM anager, 1287 private native void nativeGatherSurroundingText(long nativeContextualSearchM anager,
1195 String selection, boolean useResolvedSearchTerm, ContentViewCore bas eContentViewCore, 1288 String selection, boolean useResolvedSearchTerm, ContentViewCore bas eContentViewCore,
1196 boolean maySendBasePageUrl); 1289 boolean maySendBasePageUrl);
1290 private native String nativeGetTargetLanguage(long nativeContextualSearchMan ager);
1291 private native String nativeGetAcceptLanguages(long nativeContextualSearchMa nager);
1197 } 1292 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698