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 #include "omnibox_prerender.h" 6 7 #include "base/android/jni_string.h" 8 #include "base/logging.h" 9 #include "chrome/browser/autocomplete/autocomplete_match.h" 10 #include "chrome/browser/autocomplete/autocomplete_result.h" 11 #include "chrome/browser/predictors/autocomplete_action_predictor.h" 12 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile_android.h" 15 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents_view.h" 17 #include "jni/OmniboxPrerender_jni.h" 18 #include "url/gurl.h" 19 20 using predictors::AutocompleteActionPredictor; 21 using predictors::AutocompleteActionPredictorFactory; 22 23 OmniboxPrerender::OmniboxPrerender(JNIEnv* env, jobject obj) 24 : weak_java_omnibox_(env, obj) { 25 } 26 27 OmniboxPrerender::~OmniboxPrerender() { 28 } 29 30 static jint Init(JNIEnv* env, jobject obj) { 31 OmniboxPrerender* omnibox = new OmniboxPrerender(env, obj); 32 return reinterpret_cast<jint>(omnibox); 33 } 34 35 bool RegisterOmniboxPrerender(JNIEnv* env) { 36 return RegisterNativesImpl(env); 37 } 38 39 void OmniboxPrerender::Clear(JNIEnv* env, 40 jobject obj, 41 jobject j_profile_android) { 42 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); 43 DCHECK(profile); 44 if (!profile) 45 return; 46 AutocompleteActionPredictor* action_predictor = 47 AutocompleteActionPredictorFactory::GetForProfile(profile); 48 action_predictor->ClearTransitionalMatches(); 49 } 50 51 void OmniboxPrerender::InitializeForProfile( 52 JNIEnv* env, 53 jobject obj, 54 jobject j_profile_android) { 55 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); 56 // Initialize the AutocompleteActionPredictor for this profile. 57 // It needs to register for notifications as part of its initialization. 58 AutocompleteActionPredictorFactory::GetForProfile(profile); 59 } 60 61 void OmniboxPrerender::PrerenderMaybe(JNIEnv* env, 62 jobject obj, 63 jstring j_url, 64 jstring j_current_url, 65 jint jsource_match, 66 jobject j_profile_android, 67 jint native_web_contents) { 68 AutocompleteResult* autocomplete_result = 69 reinterpret_cast<AutocompleteResult*>(jsource_match); 70 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); 71 base::string16 url_string = 72 base::android::ConvertJavaStringToUTF16(env, j_url); 73 base::string16 current_url_string = 74 base::android::ConvertJavaStringToUTF16(env, j_current_url); 75 content::WebContents* web_contents = 76 reinterpret_cast<content::WebContents*>(native_web_contents); 77 // TODO(apiccion) Use a delegate for communicating with web_contents. 78 // This can happen in OmniboxTests since the results are generated 79 // in Java only. 80 if (!autocomplete_result) 81 return; 82 if (!profile) 83 return; 84 85 const AutocompleteResult::const_iterator default_match( 86 autocomplete_result->default_match()); 87 if (default_match == autocomplete_result->end()) 88 return; 89 90 AutocompleteActionPredictor* action_predictor = 91 AutocompleteActionPredictorFactory::GetForProfile(profile); 92 if (!action_predictor) 93 return; 94 95 AutocompleteActionPredictor::Action recommended_action = 96 AutocompleteActionPredictor::ACTION_NONE; 97 if (action_predictor) { 98 action_predictor-> 99 RegisterTransitionalMatches(url_string, *autocomplete_result); 100 recommended_action = 101 action_predictor->RecommendAction(url_string, *default_match); 102 } 103 104 GURL current_url = GURL(current_url_string); 105 switch (recommended_action) { 106 case AutocompleteActionPredictor::ACTION_PRERENDER: 107 // Ask for prerendering if the destination URL is different than the 108 // current URL. 109 if (default_match->destination_url != current_url) { 110 DoPrerender( 111 *default_match, 112 profile, 113 web_contents); 114 } 115 break; 116 case AutocompleteActionPredictor::ACTION_PRECONNECT: 117 // TODO (apiccion) add preconnect logic 118 break; 119 case AutocompleteActionPredictor::ACTION_NONE: 120 break; 121 default: 122 NOTREACHED(); 123 break; 124 } 125 } 126 127 void OmniboxPrerender::DoPrerender(const AutocompleteMatch& match, 128 Profile* profile, 129 content::WebContents* web_contents) { 130 DCHECK(profile); 131 if (!profile) 132 return; 133 DCHECK(web_contents); 134 if (!web_contents) 135 return; 136 gfx::Rect container_bounds; 137 web_contents->GetView()->GetContainerBounds(&container_bounds); 138 predictors::AutocompleteActionPredictorFactory::GetForProfile(profile)-> 139 StartPrerendering( 140 match.destination_url, 141 web_contents->GetController().GetSessionStorageNamespaceMap(), 142 container_bounds.size()); 143 } 144