Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2011 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 #include "chrome/browser/android/omnibox/autocomplete_controller_android.h" | |
| 6 | |
| 7 #include "base/android/jni_android.h" | |
| 8 #include "base/android/jni_string.h" | |
| 9 #include "base/prefs/pref_service.h" | |
| 10 #include "base/strings/string16.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | |
| 12 #include "base/time/time.h" | |
| 13 #include "base/timer/timer.h" | |
| 14 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | |
| 15 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" | |
| 16 #include "chrome/browser/autocomplete/autocomplete_controller.h" | |
| 17 #include "chrome/browser/autocomplete/autocomplete_input.h" | |
| 18 #include "chrome/browser/autocomplete/autocomplete_match.h" | |
| 19 #include "chrome/browser/autocomplete/shortcuts_backend_factory.h" | |
| 20 #include "chrome/browser/browser_process.h" | |
| 21 #include "chrome/browser/chrome_notification_types.h" | |
| 22 #include "chrome/browser/omnibox/omnibox_field_trial.h" | |
| 23 #include "chrome/browser/omnibox/omnibox_log.h" | |
| 24 #include "chrome/browser/profiles/incognito_helpers.h" | |
| 25 #include "chrome/browser/profiles/profile_android.h" | |
| 26 #include "chrome/browser/profiles/profile_manager.h" | |
| 27 #include "chrome/browser/search_engines/template_url_service.h" | |
| 28 #include "chrome/browser/search_engines/template_url_service_factory.h" | |
| 29 #include "chrome/browser/sessions/session_id.h" | |
| 30 #include "chrome/browser/ui/toolbar/toolbar_model.h" | |
| 31 #include "chrome/common/autocomplete_match_type.h" | |
| 32 #include "chrome/common/pref_names.h" | |
| 33 #include "chrome/common/url_constants.h" | |
| 34 #include "components/keyed_service/content/browser_context_dependency_manager.h" | |
| 35 #include "content/public/browser/notification_details.h" | |
| 36 #include "content/public/browser/notification_service.h" | |
| 37 #include "content/public/browser/notification_source.h" | |
| 38 #include "content/public/browser/web_contents.h" | |
| 39 #include "content/public/common/url_constants.h" | |
| 40 #include "jni/AutocompleteController_jni.h" | |
| 41 #include "net/base/escape.h" | |
| 42 #include "net/base/net_util.h" | |
| 43 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | |
| 44 #include "ui/base/resource/resource_bundle.h" | |
| 45 | |
| 46 using base::android::AttachCurrentThread; | |
| 47 using base::android::ConvertJavaStringToUTF16; | |
| 48 using base::android::ConvertUTF8ToJavaString; | |
| 49 using base::android::ConvertUTF16ToJavaString; | |
| 50 | |
| 51 namespace { | |
| 52 | |
| 53 // TODO(newt): just use chrome::kChromeUINativeNewTabURL once it's landed. | |
| 54 const char kChromeUINativeNewTabURL[] = "chrome-native://newtab/"; | |
|
Ted C
2014/05/14 00:49:23
this has in fact landed, so mind cleaning up the T
Maria
2014/05/14 01:54:22
Done.
| |
| 55 | |
| 56 const int kAndroidAutocompleteProviders = | |
| 57 AutocompleteClassifier::kDefaultOmniboxProviders; | |
| 58 | |
| 59 /** | |
| 60 * A prefetcher class responsible for triggering zero suggest prefetch. | |
| 61 * The prefetch occurs as a side-effect of calling StartZeroSuggest() on | |
| 62 * the AutocompleteController object. | |
| 63 */ | |
| 64 class ZeroSuggestPrefetcher : public AutocompleteControllerDelegate { | |
| 65 public: | |
| 66 explicit ZeroSuggestPrefetcher(Profile* profile); | |
| 67 | |
| 68 private: | |
| 69 virtual ~ZeroSuggestPrefetcher(); | |
| 70 void SelfDestruct(); | |
| 71 | |
| 72 // AutocompleteControllerDelegate: | |
| 73 virtual void OnResultChanged(bool default_match_changed) OVERRIDE; | |
| 74 | |
| 75 scoped_ptr<AutocompleteController> controller_; | |
| 76 base::OneShotTimer<ZeroSuggestPrefetcher> expire_timer_; | |
| 77 }; | |
| 78 | |
| 79 ZeroSuggestPrefetcher::ZeroSuggestPrefetcher(Profile* profile) : controller_( | |
| 80 new AutocompleteController(profile, this, | |
| 81 AutocompleteProvider::TYPE_ZERO_SUGGEST)) { | |
| 82 // Creating an arbitrary fake_request_source to avoid passing in an invalid | |
| 83 // AutocompleteInput object. | |
| 84 base::string16 fake_request_source(base::ASCIIToUTF16( | |
| 85 "http://www.foobarbazblah.com")); | |
| 86 controller_->StartZeroSuggest(AutocompleteInput( | |
| 87 fake_request_source, base::string16::npos, base::string16(), | |
| 88 GURL(fake_request_source), AutocompleteInput::INVALID_SPEC, | |
| 89 false, false, true, true)); | |
| 90 // Delete ourselves after 10s. This is enough time to cache results or | |
| 91 // give up if the results haven't been received. | |
| 92 expire_timer_.Start(FROM_HERE, | |
| 93 base::TimeDelta::FromMilliseconds(10000), | |
| 94 this, &ZeroSuggestPrefetcher::SelfDestruct); | |
| 95 } | |
| 96 | |
| 97 ZeroSuggestPrefetcher::~ZeroSuggestPrefetcher() { | |
| 98 } | |
| 99 | |
| 100 void ZeroSuggestPrefetcher::SelfDestruct() { | |
| 101 delete this; | |
| 102 } | |
| 103 | |
| 104 void ZeroSuggestPrefetcher::OnResultChanged(bool default_match_changed) { | |
| 105 // Nothing to do here, the results have been cached. | |
| 106 // We don't want to trigger deletion here because this is being called by the | |
| 107 // AutocompleteController object. | |
| 108 } | |
| 109 | |
| 110 } // namespace | |
| 111 | |
| 112 AutocompleteControllerAndroid::AutocompleteControllerAndroid(Profile* profile) | |
| 113 : autocomplete_controller_(new AutocompleteController( | |
| 114 profile, this, kAndroidAutocompleteProviders)), | |
| 115 inside_classify_(false), | |
| 116 profile_(profile) { | |
| 117 } | |
| 118 | |
| 119 void AutocompleteControllerAndroid::Start(JNIEnv* env, | |
| 120 jobject obj, | |
| 121 jstring j_text, | |
| 122 jstring j_desired_tld, | |
| 123 jstring j_current_url, | |
| 124 bool prevent_inline_autocomplete, | |
| 125 bool prefer_keyword, | |
| 126 bool allow_exact_keyword_match, | |
| 127 bool want_asynchronous_matches) { | |
| 128 if (autocomplete_controller_ == NULL) | |
|
Ted C
2014/05/14 00:49:23
I think in chrome, it is now more common to see
i
Maria
2014/05/14 01:54:22
Done.
| |
| 129 return; | |
| 130 | |
| 131 base::string16 desired_tld; | |
| 132 GURL current_url; | |
| 133 if (j_current_url != NULL) | |
| 134 current_url = GURL(ConvertJavaStringToUTF16(env, j_current_url)); | |
| 135 if (j_desired_tld != NULL) | |
| 136 desired_tld = ConvertJavaStringToUTF16(env, j_desired_tld); | |
| 137 base::string16 text = ConvertJavaStringToUTF16(env, j_text); | |
| 138 AutocompleteInput::PageClassification page_classification = | |
| 139 AutocompleteInput::OTHER; | |
| 140 input_ = AutocompleteInput( | |
| 141 text, base::string16::npos, desired_tld, current_url, | |
| 142 page_classification, prevent_inline_autocomplete, prefer_keyword, | |
| 143 allow_exact_keyword_match, want_asynchronous_matches); | |
| 144 autocomplete_controller_->Start(input_); | |
| 145 } | |
| 146 | |
| 147 ScopedJavaLocalRef<jobject> AutocompleteControllerAndroid::Classify(JNIEnv* env, | |
| 148 jobject obj, | |
|
Ted C
2014/05/14 00:49:23
indenting is off on these params (and else where b
Maria
2014/05/14 01:54:22
Done.
| |
| 149 jstring j_text) { | |
| 150 if (autocomplete_controller_ == NULL) | |
| 151 return ScopedJavaLocalRef<jobject>(); | |
| 152 | |
| 153 inside_classify_ = true; | |
| 154 Start(env, obj, j_text, NULL, NULL, true, false, false, false); | |
| 155 inside_classify_ = false; | |
| 156 DCHECK(autocomplete_controller_->done()); | |
| 157 const AutocompleteResult& result = autocomplete_controller_->result(); | |
| 158 if (result.empty()) | |
| 159 return ScopedJavaLocalRef<jobject>(); | |
| 160 | |
| 161 return BuildOmniboxSuggestion(env, *result.begin()); | |
| 162 } | |
| 163 | |
| 164 void AutocompleteControllerAndroid::StartZeroSuggest(JNIEnv* env, | |
| 165 jobject obj, | |
| 166 jstring j_omnibox_text, | |
| 167 jstring j_current_url, | |
| 168 jboolean is_query_in_omnibox, | |
| 169 jboolean focused_from_fakebox) { | |
| 170 if (autocomplete_controller_ == NULL) | |
| 171 return; | |
| 172 | |
| 173 base::string16 url = ConvertJavaStringToUTF16(env, j_current_url); | |
| 174 const GURL current_url = GURL(url); | |
| 175 base::string16 omnibox_text = ConvertJavaStringToUTF16(env, j_omnibox_text); | |
| 176 | |
| 177 // If omnibox text is empty, set it to the current URL for the purposes of | |
| 178 // populating the verbatim match. | |
| 179 if (omnibox_text.empty()) | |
| 180 omnibox_text = url; | |
| 181 | |
| 182 input_ = AutocompleteInput( | |
| 183 omnibox_text, base::string16::npos, base::string16(), current_url, | |
| 184 ClassifyPage(current_url, is_query_in_omnibox, focused_from_fakebox), | |
| 185 false, false, true, true); | |
| 186 autocomplete_controller_->StartZeroSuggest(input_); | |
| 187 } | |
| 188 | |
| 189 void AutocompleteControllerAndroid::Stop(JNIEnv* env, | |
| 190 jobject obj, | |
| 191 bool clear_results) { | |
| 192 if (autocomplete_controller_ != NULL) | |
| 193 autocomplete_controller_->Stop(clear_results); | |
| 194 } | |
| 195 | |
| 196 void AutocompleteControllerAndroid::ResetSession(JNIEnv* env, jobject obj) { | |
| 197 if (autocomplete_controller_ != NULL) | |
| 198 autocomplete_controller_->ResetSession(); | |
| 199 } | |
| 200 | |
| 201 void AutocompleteControllerAndroid::OnSuggestionSelected( | |
| 202 JNIEnv* env, | |
| 203 jobject obj, | |
| 204 jint selected_index, | |
| 205 jstring j_current_url, | |
| 206 jboolean is_query_in_omnibox, | |
| 207 jboolean focused_from_fakebox, | |
| 208 jlong elapsed_time_since_first_modified, | |
| 209 jobject j_web_contents) { | |
| 210 base::string16 url = ConvertJavaStringToUTF16(env, j_current_url); | |
| 211 const GURL current_url = GURL(url); | |
| 212 AutocompleteInput::PageClassification current_page_classification = | |
| 213 ClassifyPage(current_url, is_query_in_omnibox, focused_from_fakebox); | |
| 214 const base::TimeTicks& now(base::TimeTicks::Now()); | |
| 215 content::WebContents* web_contents = | |
| 216 content::WebContents::FromJavaWebContents(j_web_contents); | |
| 217 | |
| 218 OmniboxLog log( | |
| 219 input_.text(), | |
| 220 false, /* don't know */ | |
| 221 input_.type(), | |
| 222 true, | |
| 223 selected_index, | |
| 224 false, | |
| 225 SessionID::IdForTab(web_contents), | |
| 226 current_page_classification, | |
| 227 base::TimeDelta::FromMilliseconds(elapsed_time_since_first_modified), | |
| 228 base::string16::npos, | |
| 229 now - autocomplete_controller_->last_time_default_match_changed(), | |
| 230 autocomplete_controller_->result()); | |
| 231 autocomplete_controller_->AddProvidersInfo(&log.providers_info); | |
| 232 | |
| 233 content::NotificationService::current()->Notify( | |
| 234 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | |
| 235 content::Source<Profile>(profile_), | |
| 236 content::Details<OmniboxLog>(&log)); | |
| 237 } | |
| 238 | |
| 239 void AutocompleteControllerAndroid::DeleteSuggestion(JNIEnv* env, | |
| 240 jobject obj, | |
| 241 int selected_index) { | |
| 242 const AutocompleteResult& result = autocomplete_controller_->result(); | |
| 243 const AutocompleteMatch& match = result.match_at(selected_index); | |
| 244 if (match.SupportsDeletion()) | |
| 245 autocomplete_controller_->DeleteMatch(match); | |
| 246 } | |
| 247 | |
| 248 ScopedJavaLocalRef<jstring> | |
| 249 AutocompleteControllerAndroid::UpdateMatchDestinationURL( | |
| 250 JNIEnv* env, | |
| 251 jobject obj, | |
| 252 jint selected_index, | |
| 253 jlong elapsed_time_since_input_change) { | |
| 254 // In rare cases, we navigate to cached matches and the underlying result | |
| 255 // has already been cleared, in that case ignore the URL update. | |
| 256 if (autocomplete_controller_->result().empty()) | |
| 257 return ScopedJavaLocalRef<jstring>(); | |
| 258 | |
| 259 AutocompleteMatch match( | |
| 260 autocomplete_controller_->result().match_at(selected_index)); | |
| 261 autocomplete_controller_->UpdateMatchDestinationURL( | |
| 262 base::TimeDelta::FromMilliseconds(elapsed_time_since_input_change), | |
| 263 &match); | |
| 264 return ConvertUTF8ToJavaString(env, match.destination_url.spec()); | |
| 265 } | |
| 266 | |
| 267 void AutocompleteControllerAndroid::Shutdown() { | |
| 268 autocomplete_controller_.reset(); | |
| 269 | |
| 270 JNIEnv* env = AttachCurrentThread(); | |
| 271 ScopedJavaLocalRef<jobject> java_bridge = | |
| 272 weak_java_autocomplete_controller_android_.get(env); | |
| 273 if (java_bridge.obj()) | |
| 274 Java_AutocompleteController_notifyNativeDestroyed(env, java_bridge.obj()); | |
| 275 | |
| 276 weak_java_autocomplete_controller_android_.reset(); | |
| 277 } | |
| 278 | |
| 279 // static | |
| 280 AutocompleteControllerAndroid* | |
| 281 AutocompleteControllerAndroid::Factory::GetForProfile( | |
| 282 Profile* profile, JNIEnv* env, jobject obj) { | |
| 283 AutocompleteControllerAndroid* bridge = | |
| 284 static_cast<AutocompleteControllerAndroid*>( | |
| 285 GetInstance()->GetServiceForBrowserContext(profile, true)); | |
| 286 bridge->InitJNI(env, obj); | |
| 287 return bridge; | |
| 288 } | |
| 289 | |
| 290 AutocompleteControllerAndroid::Factory* | |
| 291 AutocompleteControllerAndroid::Factory::GetInstance() { | |
| 292 return Singleton<AutocompleteControllerAndroid::Factory>::get(); | |
| 293 } | |
| 294 | |
| 295 content::BrowserContext* | |
| 296 AutocompleteControllerAndroid::Factory::GetBrowserContextToUse( | |
| 297 content::BrowserContext* context) const { | |
| 298 return chrome::GetBrowserContextOwnInstanceInIncognito(context); | |
| 299 } | |
| 300 | |
| 301 AutocompleteControllerAndroid::Factory::Factory() | |
| 302 : BrowserContextKeyedServiceFactory( | |
| 303 "AutocompleteControllerAndroid", | |
|
Maria
2014/05/14 01:54:22
Btw, I changed the key string here and I assume it
Ted C
2014/05/15 18:10:52
Correct, you just want the name to be unique...and
| |
| 304 BrowserContextDependencyManager::GetInstance()) { | |
| 305 DependsOn(ShortcutsBackendFactory::GetInstance()); | |
| 306 } | |
| 307 | |
| 308 AutocompleteControllerAndroid::Factory::~Factory() { | |
| 309 } | |
| 310 | |
| 311 KeyedService* AutocompleteControllerAndroid::Factory::BuildServiceInstanceFor( | |
| 312 content::BrowserContext* profile) const { | |
| 313 return new AutocompleteControllerAndroid(static_cast<Profile*>(profile)); | |
| 314 } | |
| 315 | |
| 316 AutocompleteControllerAndroid::~AutocompleteControllerAndroid() { | |
| 317 } | |
| 318 | |
| 319 void AutocompleteControllerAndroid::InitJNI(JNIEnv* env, jobject obj) { | |
| 320 weak_java_autocomplete_controller_android_ = | |
| 321 JavaObjectWeakGlobalRef(env, obj); | |
| 322 } | |
| 323 | |
| 324 void AutocompleteControllerAndroid::OnResultChanged( | |
| 325 bool default_match_changed) { | |
| 326 if (autocomplete_controller_.get() != NULL && !inside_classify_) | |
| 327 NotifySuggestionsReceived(autocomplete_controller_->result()); | |
| 328 } | |
| 329 | |
| 330 void AutocompleteControllerAndroid::NotifySuggestionsReceived( | |
| 331 const AutocompleteResult& autocomplete_result) { | |
| 332 JNIEnv* env = AttachCurrentThread(); | |
| 333 ScopedJavaLocalRef<jobject> java_bridge = | |
| 334 weak_java_autocomplete_controller_android_.get(env); | |
| 335 if (!java_bridge.obj()) | |
| 336 return; | |
| 337 | |
| 338 ScopedJavaLocalRef<jobject> suggestion_list_obj = | |
| 339 Java_AutocompleteController_createOmniboxSuggestionList( | |
| 340 env, autocomplete_result.size()); | |
| 341 for (size_t i = 0; i < autocomplete_result.size(); ++i) { | |
| 342 ScopedJavaLocalRef<jobject> j_omnibox_suggestion = | |
| 343 BuildOmniboxSuggestion(env, autocomplete_result.match_at(i)); | |
| 344 Java_AutocompleteController_addOmniboxSuggestionToList( | |
| 345 env, suggestion_list_obj.obj(), j_omnibox_suggestion.obj()); | |
| 346 } | |
| 347 | |
| 348 // Get the inline-autocomplete text. | |
| 349 const AutocompleteResult::const_iterator default_match( | |
| 350 autocomplete_result.default_match()); | |
| 351 base::string16 inline_autocomplete_text; | |
| 352 if (default_match != autocomplete_result.end()) { | |
| 353 inline_autocomplete_text = default_match->inline_autocompletion; | |
| 354 } | |
| 355 ScopedJavaLocalRef<jstring> inline_text = | |
| 356 ConvertUTF16ToJavaString(env, inline_autocomplete_text); | |
| 357 jlong j_autocomplete_result = | |
| 358 reinterpret_cast<intptr_t>(&(autocomplete_result)); | |
| 359 Java_AutocompleteController_onSuggestionsReceived(env, | |
| 360 java_bridge.obj(), | |
| 361 suggestion_list_obj.obj(), | |
| 362 inline_text.obj(), | |
| 363 j_autocomplete_result); | |
| 364 } | |
| 365 | |
| 366 ScopedJavaLocalRef<jobject> | |
| 367 AutocompleteControllerAndroid::BuildOmniboxSuggestion( | |
| 368 JNIEnv* env, | |
| 369 const AutocompleteMatch& match) { | |
| 370 ScopedJavaLocalRef<jstring> contents = | |
| 371 ConvertUTF16ToJavaString(env, match.contents); | |
| 372 ScopedJavaLocalRef<jstring> description = | |
| 373 ConvertUTF16ToJavaString(env, match.description); | |
| 374 ScopedJavaLocalRef<jstring> fill_into_edit = | |
| 375 ConvertUTF16ToJavaString(env, match.fill_into_edit); | |
| 376 ScopedJavaLocalRef<jstring> destination_url = | |
| 377 ConvertUTF8ToJavaString(env, match.destination_url.spec()); | |
| 378 // Note that we are also removing 'www' host from formatted url. | |
| 379 ScopedJavaLocalRef<jstring> formatted_url = ConvertUTF16ToJavaString(env, | |
| 380 FormatURLUsingAcceptLanguages(match.stripped_destination_url)); | |
| 381 return Java_AutocompleteController_buildOmniboxSuggestion( | |
| 382 env, match.type, match.relevance, | |
|
Ted C
2014/05/14 00:49:23
I think each one of these needs to go on a new lin
Maria
2014/05/14 01:54:22
Done. For the record, I think it's crazy to be pas
| |
| 383 match.transition, contents.obj(), description.obj(), | |
| 384 fill_into_edit.obj(), destination_url.obj(), formatted_url.obj(), | |
| 385 match.starred, match.SupportsDeletion()); | |
| 386 } | |
| 387 | |
| 388 base::string16 AutocompleteControllerAndroid::FormatURLUsingAcceptLanguages( | |
| 389 GURL url) { | |
| 390 if (profile_ == NULL) { | |
|
Ted C
2014/05/14 00:49:23
no braces needed.
Maria
2014/05/14 01:54:22
Done.
| |
| 391 return base::string16(); | |
| 392 } | |
| 393 std::string languages( | |
| 394 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); | |
| 395 | |
| 396 return net::FormatUrl(url, languages, net::kFormatUrlOmitAll, | |
| 397 net::UnescapeRule::SPACES, NULL, NULL, NULL); | |
| 398 } | |
| 399 | |
| 400 AutocompleteInput::PageClassification | |
| 401 AutocompleteControllerAndroid::ClassifyPage(const GURL& gurl, | |
| 402 bool is_query_in_omnibox, | |
| 403 bool focused_from_fakebox) const { | |
| 404 if (!gurl.is_valid()) | |
| 405 return AutocompleteInput::INVALID_SPEC; | |
| 406 | |
| 407 const std::string& url = gurl.spec(); | |
| 408 | |
| 409 if (gurl.SchemeIs(content::kChromeUIScheme) && | |
| 410 gurl.host() == chrome::kChromeUINewTabHost) { | |
| 411 return AutocompleteInput::NTP; | |
| 412 } | |
| 413 if (url == kChromeUINativeNewTabURL) { | |
| 414 return focused_from_fakebox ? | |
| 415 AutocompleteInput::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS : | |
| 416 AutocompleteInput::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS; | |
| 417 } | |
| 418 if (url == content::kAboutBlankURL) | |
| 419 return AutocompleteInput::BLANK; | |
| 420 | |
| 421 if (url == profile_->GetPrefs()->GetString(prefs::kHomePage)) | |
| 422 return AutocompleteInput::HOME_PAGE; | |
| 423 if (is_query_in_omnibox) | |
| 424 return AutocompleteInput::SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT; | |
| 425 | |
| 426 bool is_search_url = TemplateURLServiceFactory::GetForProfile(profile_)-> | |
| 427 IsSearchResultsPageFromDefaultSearchProvider(gurl); | |
| 428 if (is_search_url) | |
| 429 return AutocompleteInput::SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT; | |
| 430 return AutocompleteInput::OTHER; | |
| 431 } | |
| 432 | |
| 433 static jlong Init(JNIEnv* env, jobject obj, jobject jprofile) { | |
| 434 Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); | |
| 435 if (!profile) | |
| 436 return 0; | |
| 437 | |
| 438 AutocompleteControllerAndroid* native_bridge = | |
| 439 AutocompleteControllerAndroid::Factory::GetForProfile(profile, env, obj); | |
| 440 return reinterpret_cast<intptr_t>(native_bridge); | |
| 441 } | |
| 442 | |
| 443 static jstring QualifyPartialURLQuery( | |
| 444 JNIEnv* env, jclass clazz, jstring jquery) { | |
| 445 Profile* profile = ProfileManager::GetActiveUserProfile(); | |
| 446 if (!profile) | |
| 447 return NULL; | |
| 448 AutocompleteMatch match; | |
| 449 base::string16 query_string(ConvertJavaStringToUTF16(env, jquery)); | |
| 450 AutocompleteClassifierFactory::GetForProfile(profile)->Classify( | |
| 451 query_string, false, false, AutocompleteInput::INVALID_SPEC, &match, | |
| 452 NULL); | |
| 453 if (!match.destination_url.is_valid()) | |
| 454 return NULL; | |
| 455 | |
| 456 // Only return a URL if the match is a URL type. | |
| 457 if (match.type != AutocompleteMatchType::URL_WHAT_YOU_TYPED && | |
| 458 match.type != AutocompleteMatchType::HISTORY_URL && | |
| 459 match.type != AutocompleteMatchType::NAVSUGGEST) | |
| 460 return NULL; | |
| 461 | |
| 462 // As we are returning to Java, it is fine to call Release(). | |
| 463 return ConvertUTF8ToJavaString(env, match.destination_url.spec()).Release(); | |
| 464 } | |
| 465 | |
| 466 static void PrefetchZeroSuggestResults(JNIEnv* env, jclass clazz) { | |
| 467 Profile* profile = ProfileManager::GetActiveUserProfile(); | |
| 468 if (!profile) | |
| 469 return; | |
| 470 | |
| 471 if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) | |
| 472 return; | |
| 473 | |
| 474 // ZeroSuggestPrefetcher deletes itself after it's done prefetching. | |
| 475 new ZeroSuggestPrefetcher(profile); | |
| 476 } | |
| 477 | |
| 478 // Register native methods | |
| 479 bool RegisterAutocompleteControllerAndroid(JNIEnv* env) { | |
| 480 return RegisterNativesImpl(env); | |
| 481 } | |
| OLD | NEW |