Home | History | Annotate | Download | only in omnibox
      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