1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.contextualsearch;
6 
7 import android.net.Uri;
8 import android.text.TextUtils;
9 
10 import org.chromium.base.Log;
11 import org.chromium.base.annotations.CalledByNative;
12 import org.chromium.base.annotations.NativeMethods;
13 import org.chromium.chrome.browser.contextualsearch.ResolvedSearchTerm.CardTag;
14 import org.chromium.chrome.browser.tab.Tab;
15 import org.chromium.content_public.browser.WebContents;
16 
17 /**
18  * Deprecated class to provide an alternate access point to the server's Resolve request
19  * for experimentation purposes.
20  * TODO(donnd): remove this class and its associated native class.
21  */
22 public class SimpleSearchTermResolver {
23     /**
24      * Provides a callback that will be called when the server responds with the Resolved
25      * Search Term, or an error.
26      */
27     public interface ResolveResponse {
onResolveResponse(ResolvedSearchTerm resolvedSearchTerm, Uri searchUri)28         void onResolveResponse(ResolvedSearchTerm resolvedSearchTerm, Uri searchUri);
29     }
30 
31     private static final String TAG = "TTS Resolver";
32 
33     // Our singleton instance.
34     private static SimpleSearchTermResolver sInstance;
35 
36     // Pointer to the native instance of this class.
37     private long mNativePointer;
38     private Tab mTabInUse;
39     private ResolveResponse mResponseCallback;
40 
41     private ContextualSearchContext mContext;
42 
43     /** Gets the singleton instance for this class. */
getInstance()44     public static SimpleSearchTermResolver getInstance() {
45         if (sInstance == null) sInstance = new SimpleSearchTermResolver();
46         return sInstance;
47     }
48 
49     /**
50      * Starts a Search Term Resolution request for the given {@link ContextualSearchContext}.
51      * @param baseWebContents Provides some context info, like the URL of the page.
52      * @param contextualSearchContext Provides most of the Context info, including selection
53      *        location.
54      * @param responseCallback A {@link ResolveResponse} instance, so we can call
55      *        {@link ResolveResponse#onResolveResponse} when the response comes in.
56      */
startSearchTermResolutionRequest(WebContents baseWebContents, ContextualSearchContext contextualSearchContext, ResolveResponse responseCallback)57     public void startSearchTermResolutionRequest(WebContents baseWebContents,
58             ContextualSearchContext contextualSearchContext, ResolveResponse responseCallback) {
59         assert mResponseCallback == null;
60         mResponseCallback = responseCallback;
61         if (baseWebContents != null && contextualSearchContext != null
62                 && contextualSearchContext.canResolve()) {
63             Log.i(TAG,
64                     "calling SimpleSearchTermResolverJni.get().startSearchTermResolutionRequest.");
65             SimpleSearchTermResolverJni.get().startSearchTermResolutionRequest(mNativePointer,
66                     SimpleSearchTermResolver.this, contextualSearchContext, baseWebContents);
67         }
68     }
69 
70     /**
71      * Called in response to the
72      * {@link
73      * ContextualSearchManager#SimpleSearchTermResolverJni.get().startSearchTermResolutionRequest}
74      * method. If {@code SimpleSearchTermResolverJni.get().startSearchTermResolutionRequest} is
75      * called with a previous request sill pending our native delegate is supposed to cancel all
76      * previous requests.  So this code should only be called with data corresponding to the most
77      * recent request.
78      * @param isNetworkUnavailable Indicates if the network is unavailable, in which case all other
79      *        parameters should be ignored.
80      * @param responseCode The HTTP response code. If the code is not OK, the query should be
81      *        ignored.
82      * @param searchTerm The term to use in our subsequent search.
83      * @param displayText The text to display in our UX.
84      * @param alternateTerm The alternate term to display on the results page.
85      * @param mid the MID for an entity to use to trigger a Knowledge Panel, or an empty string.
86      *        A MID is a unique identifier for an entity in the Search Knowledge Graph.
87      * @param doPreventPreload Whether we should prevent preloading on this search.
88      * @param selectionStartAdjust A positive number of characters that the start of the existing
89      *        selection should be expanded by.
90      * @param selectionEndAdjust A positive number of characters that the end of the existing
91      *        selection should be expanded by.
92      * @param contextLanguage The language of the original search term, or an empty string.
93      * @param thumbnailUrl The URL of the thumbnail to display in our UX.
94      * @param caption The caption to display.
95      * @param quickActionUri The URI for the intent associated with the quick action.
96      * @param quickActionCategory The {@link QuickActionCategory} for the quick action.
97      * @param loggedEventId The EventID logged by the server, which should be recorded and sent back
98      *        to the server along with user action results in a subsequent request.
99      * @param searchUrlFull The URL for the full search to present in the overlay, or empty.
100      * @param searchUrlPreload The URL for the search to preload into the overlay, or empty.
101      * @param cocaCardTag The primary internal Coca card tag for the response, or {@code 0} if none.
102      */
103     @CalledByNative
onSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode, final String searchTerm, final String displayText, final String alternateTerm, final String mid, boolean doPreventPreload, int selectionStartAdjust, int selectionEndAdjust, final String contextLanguage, final String thumbnailUrl, final String caption, final String quickActionUri, @QuickActionCategory final int quickActionCategory, final long loggedEventId, final String searchUrlFull, final String searchUrlPreload, @CardTag final int cocaCardTag)104     public void onSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
105             final String searchTerm, final String displayText, final String alternateTerm,
106             final String mid, boolean doPreventPreload, int selectionStartAdjust,
107             int selectionEndAdjust, final String contextLanguage, final String thumbnailUrl,
108             final String caption, final String quickActionUri,
109             @QuickActionCategory final int quickActionCategory, final long loggedEventId,
110             final String searchUrlFull, final String searchUrlPreload,
111             @CardTag final int cocaCardTag) {
112         ResolvedSearchTerm resolvedSearchTerm =
113                 new ResolvedSearchTerm
114                         .Builder(isNetworkUnavailable, responseCode, searchTerm, displayText,
115                                 alternateTerm, mid, doPreventPreload, selectionStartAdjust,
116                                 selectionEndAdjust, contextLanguage, thumbnailUrl, caption,
117                                 quickActionUri, quickActionCategory, loggedEventId, searchUrlFull,
118                                 searchUrlPreload, cocaCardTag)
119                         .build();
120         Log.v(TAG, "onSearchTermResolutionResponse received with " + resolvedSearchTerm);
121         if (!TextUtils.isEmpty(resolvedSearchTerm.searchTerm())) {
122             ResolveResponse responseCallback = mResponseCallback;
123             mResponseCallback = null;
124             assert responseCallback != null;
125             Uri searchUrl = Uri.parse(makeSearchUrl(resolvedSearchTerm));
126             responseCallback.onResolveResponse(resolvedSearchTerm, searchUrl);
127         }
128         mTabInUse = null;
129     }
130 
131     /** Constructs the singleton instance. */
SimpleSearchTermResolver()132     private SimpleSearchTermResolver() {
133         mNativePointer = SimpleSearchTermResolverJni.get().init(SimpleSearchTermResolver.this);
134     }
135 
136     /** Makes a Search URL from the given {@link ResolvedSearchTerm}. */
makeSearchUrl(ResolvedSearchTerm resolvedSearchTerm)137     private String makeSearchUrl(ResolvedSearchTerm resolvedSearchTerm) {
138         return new ContextualSearchRequest(resolvedSearchTerm.searchTerm()).getSearchUrl();
139     }
140 
141     /**
142      * This method should be called to clean up storage when an instance of this class is
143      * no longer in use.  The SimpleSearchTermResolverJni.get().destroy will call the destructor on
144      * the native instance.
145      */
destroy()146     void destroy() {
147         assert mNativePointer != 0;
148         SimpleSearchTermResolverJni.get().destroy(mNativePointer, SimpleSearchTermResolver.this);
149         mNativePointer = 0;
150     }
151 
152     @NativeMethods
153     interface Natives {
init(SimpleSearchTermResolver caller)154         long init(SimpleSearchTermResolver caller);
destroy(long nativeSimpleSearchTermResolver, SimpleSearchTermResolver caller)155         void destroy(long nativeSimpleSearchTermResolver, SimpleSearchTermResolver caller);
startSearchTermResolutionRequest(long nativeSimpleSearchTermResolver, SimpleSearchTermResolver caller, ContextualSearchContext contextualSearchContext, WebContents baseWebContents)156         void startSearchTermResolutionRequest(long nativeSimpleSearchTermResolver,
157                 SimpleSearchTermResolver caller, ContextualSearchContext contextualSearchContext,
158                 WebContents baseWebContents);
159     }
160 }
161