1 // Copyright 2013 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.search_engines; 6 7 import org.chromium.base.CalledByNative; 8 import org.chromium.base.ObserverList; 9 import org.chromium.base.ThreadUtils; 10 11 import java.util.ArrayList; 12 import java.util.List; 13 14 /** 15 * Android wrapper of the TemplateUrlService which provides access from the Java 16 * layer. 17 * 18 * Only usable from the UI thread as it's primary purpose is for supporting the Android 19 * preferences UI. 20 * 21 * See components/search_engines/template_url_service.h for more details. 22 */ 23 public class TemplateUrlService { 24 25 /** 26 * This listener will be notified when template url service is done loading. 27 */ 28 public interface LoadListener { onTemplateUrlServiceLoaded()29 public abstract void onTemplateUrlServiceLoaded(); 30 } 31 32 /** 33 * Represents search engine with its index. 34 */ 35 public static class TemplateUrl { 36 private final int mIndex; 37 private final String mShortName; 38 private final String mKeyword; 39 40 @CalledByNative("TemplateUrl") create(int id, String shortName, String keyword)41 public static TemplateUrl create(int id, String shortName, String keyword) { 42 return new TemplateUrl(id, shortName, keyword); 43 } 44 TemplateUrl(int index, String shortName, String keyword)45 public TemplateUrl(int index, String shortName, String keyword) { 46 mIndex = index; 47 mShortName = shortName; 48 mKeyword = keyword; 49 } 50 getIndex()51 public int getIndex() { 52 return mIndex; 53 } 54 getShortName()55 public String getShortName() { 56 return mShortName; 57 } 58 getKeyword()59 public String getKeyword() { 60 return mKeyword; 61 } 62 } 63 64 private static TemplateUrlService sService; 65 getInstance()66 public static TemplateUrlService getInstance() { 67 ThreadUtils.assertOnUiThread(); 68 if (sService == null) { 69 sService = new TemplateUrlService(); 70 } 71 return sService; 72 } 73 74 private final long mNativeTemplateUrlServiceAndroid; 75 private final ObserverList<LoadListener> mLoadListeners = new ObserverList<LoadListener>(); 76 TemplateUrlService()77 private TemplateUrlService() { 78 // Note that this technically leaks the native object, however, TemlateUrlService 79 // is a singleton that lives forever and there's no clean shutdown of Chrome on Android 80 mNativeTemplateUrlServiceAndroid = nativeInit(); 81 } 82 isLoaded()83 public boolean isLoaded() { 84 ThreadUtils.assertOnUiThread(); 85 return nativeIsLoaded(mNativeTemplateUrlServiceAndroid); 86 } 87 load()88 public void load() { 89 ThreadUtils.assertOnUiThread(); 90 nativeLoad(mNativeTemplateUrlServiceAndroid); 91 } 92 93 /** 94 * Get the collection of localized search engines. 95 */ getLocalizedSearchEngines()96 public List<TemplateUrl> getLocalizedSearchEngines() { 97 ThreadUtils.assertOnUiThread(); 98 int templateUrlCount = nativeGetTemplateUrlCount(mNativeTemplateUrlServiceAndroid); 99 List<TemplateUrl> templateUrls = new ArrayList<TemplateUrl>(templateUrlCount); 100 for (int i = 0; i < templateUrlCount; i++) { 101 TemplateUrl templateUrl = nativeGetPrepopulatedTemplateUrlAt( 102 mNativeTemplateUrlServiceAndroid, i); 103 if (templateUrl != null) { 104 templateUrls.add(templateUrl); 105 } 106 } 107 return templateUrls; 108 } 109 110 /** 111 * Called from native when template URL service is done loading. 112 */ 113 @CalledByNative templateUrlServiceLoaded()114 private void templateUrlServiceLoaded() { 115 ThreadUtils.assertOnUiThread(); 116 for (LoadListener listener : mLoadListeners) { 117 listener.onTemplateUrlServiceLoaded(); 118 } 119 } 120 121 /** 122 * @return The default search engine index (e.g., 0, 1, 2,...). 123 */ getDefaultSearchEngineIndex()124 public int getDefaultSearchEngineIndex() { 125 ThreadUtils.assertOnUiThread(); 126 return nativeGetDefaultSearchProvider(mNativeTemplateUrlServiceAndroid); 127 } 128 129 /** 130 * @return {@link TemplateUrlService.TemplateUrl} for the default search engine. 131 */ getDefaultSearchEngineTemplateUrl()132 public TemplateUrl getDefaultSearchEngineTemplateUrl() { 133 if (!isLoaded()) return null; 134 135 int defaultSearchEngineIndex = getDefaultSearchEngineIndex(); 136 if (defaultSearchEngineIndex == -1) return null; 137 138 assert defaultSearchEngineIndex >= 0; 139 assert defaultSearchEngineIndex < nativeGetTemplateUrlCount( 140 mNativeTemplateUrlServiceAndroid); 141 142 return nativeGetPrepopulatedTemplateUrlAt( 143 mNativeTemplateUrlServiceAndroid, defaultSearchEngineIndex); 144 } 145 146 public void setSearchEngine(int selectedIndex) { 147 ThreadUtils.assertOnUiThread(); 148 nativeSetUserSelectedDefaultSearchProvider(mNativeTemplateUrlServiceAndroid, selectedIndex); 149 } 150 151 public boolean isSearchProviderManaged() { 152 return nativeIsSearchProviderManaged(mNativeTemplateUrlServiceAndroid); 153 } 154 155 /** 156 * @return Whether or not the default search engine has search by image support. 157 */ 158 public boolean isSearchByImageAvailable() { 159 ThreadUtils.assertOnUiThread(); 160 return nativeIsSearchByImageAvailable(mNativeTemplateUrlServiceAndroid); 161 } 162 163 /** 164 * @return Whether the default configured search engine is for a Google property. 165 */ 166 public boolean isDefaultSearchEngineGoogle() { 167 return nativeIsDefaultSearchEngineGoogle(mNativeTemplateUrlServiceAndroid); 168 } 169 170 /** 171 * Registers a listener for the callback that indicates that the 172 * TemplateURLService has loaded. 173 */ 174 public void registerLoadListener(LoadListener listener) { 175 ThreadUtils.assertOnUiThread(); 176 boolean added = mLoadListeners.addObserver(listener); 177 assert added; 178 } 179 180 /** 181 * Unregisters a listener for the callback that indicates that the 182 * TemplateURLService has loaded. 183 */ 184 public void unregisterLoadListener(LoadListener listener) { 185 ThreadUtils.assertOnUiThread(); 186 boolean removed = mLoadListeners.removeObserver(listener); 187 assert removed; 188 } 189 190 /** 191 * Finds the default search engine for the default provider and returns the url query 192 * {@link String} for {@code query}. 193 * @param query The {@link String} that represents the text query the search url should 194 * represent. 195 * @return A {@link String} that contains the url of the default search engine with 196 * {@code query} inserted as the search parameter. 197 */ 198 public String getUrlForSearchQuery(String query) { 199 return nativeGetUrlForSearchQuery(mNativeTemplateUrlServiceAndroid, query); 200 } 201 202 /** 203 * Finds the default search engine for the default provider and returns the url query 204 * {@link String} for {@code query} with voice input source param set. 205 * @param query The {@link String} that represents the text query the search url should 206 * represent. 207 * @return A {@link String} that contains the url of the default search engine with 208 * {@code query} inserted as the search parameter and voice input source param set. 209 */ 210 public String getUrlForVoiceSearchQuery(String query) { 211 return nativeGetUrlForVoiceSearchQuery(mNativeTemplateUrlServiceAndroid, query); 212 } 213 214 /** 215 * Replaces the search terms from {@code query} in {@code url}. 216 * @param query The {@link String} that represents the text query that should replace the 217 * existing query in {@code url}. 218 * @param url The {@link String} that contains the search url with another search query that 219 * will be replaced with {@code query}. 220 * @return A new version of {@code url} with the search term replaced with {@code query}. 221 */ 222 public String replaceSearchTermsInUrl(String query, String url) { 223 return nativeReplaceSearchTermsInUrl(mNativeTemplateUrlServiceAndroid, query, url); 224 } 225 226 // TODO(donnd): Delete once the client no longer references it. 227 /** 228 * Finds the default search engine for the default provider and returns the url query 229 * {@link String} for {@code query} with the contextual search version param set. 230 * @param query The search term to use as the main query in the returned search url. 231 * @param alternateTerm The alternate search term to use as an alternate suggestion. 232 * @return A {@link String} that contains the url of the default search engine with 233 * {@code query} and {@code alternateTerm} inserted as parameters and contextual 234 * search and prefetch parameters set. 235 */ 236 public String getUrlForContextualSearchQuery(String query, String alternateTerm) { 237 return nativeGetUrlForContextualSearchQuery( 238 mNativeTemplateUrlServiceAndroid, query, alternateTerm, true); 239 } 240 241 /** 242 * Finds the default search engine for the default provider and returns the url query 243 * {@link String} for {@code query} with the contextual search version param set. 244 * @param query The search term to use as the main query in the returned search url. 245 * @param alternateTerm The alternate search term to use as an alternate suggestion. 246 * @param shouldPrefetch Whether the returned url should include a prefetch parameter. 247 * @return A {@link String} that contains the url of the default search engine with 248 * {@code query} and {@code alternateTerm} inserted as parameters and contextual 249 * search and prefetch parameters conditionally set. 250 */ 251 public String getUrlForContextualSearchQuery(String query, String alternateTerm, 252 boolean shouldPrefetch) { 253 return nativeGetUrlForContextualSearchQuery( 254 mNativeTemplateUrlServiceAndroid, query, alternateTerm, shouldPrefetch); 255 } 256 257 private native long nativeInit(); 258 private native void nativeLoad(long nativeTemplateUrlServiceAndroid); 259 private native boolean nativeIsLoaded(long nativeTemplateUrlServiceAndroid); 260 private native int nativeGetTemplateUrlCount(long nativeTemplateUrlServiceAndroid); 261 private native TemplateUrl nativeGetPrepopulatedTemplateUrlAt( 262 long nativeTemplateUrlServiceAndroid, int i); 263 private native void nativeSetUserSelectedDefaultSearchProvider( 264 long nativeTemplateUrlServiceAndroid, int selectedIndex); 265 private native int nativeGetDefaultSearchProvider(long nativeTemplateUrlServiceAndroid); 266 private native boolean nativeIsSearchProviderManaged(long nativeTemplateUrlServiceAndroid); 267 private native boolean nativeIsSearchByImageAvailable(long nativeTemplateUrlServiceAndroid); 268 private native boolean nativeIsDefaultSearchEngineGoogle(long nativeTemplateUrlServiceAndroid); 269 private native String nativeGetUrlForSearchQuery(long nativeTemplateUrlServiceAndroid, 270 String query); 271 private native String nativeGetUrlForVoiceSearchQuery(long nativeTemplateUrlServiceAndroid, 272 String query); 273 private native String nativeReplaceSearchTermsInUrl(long nativeTemplateUrlServiceAndroid, 274 String query, String currentUrl); 275 private native String nativeGetUrlForContextualSearchQuery(long nativeTemplateUrlServiceAndroid, 276 String query, String alternateTerm, boolean shouldPrefetch); 277 } 278