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