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