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.
5 #include "content/browser/frame_host/navigation_controller_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "content/browser/frame_host/navigation_entry_impl.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/ssl_host_state_delegate.h"
14 #include "jni/NavigationControllerImpl_jni.h"
15 #include "ui/gfx/android/java_bitmap.h"
17 using base::android::AttachCurrentThread;
18 using base::android::ConvertJavaStringToUTF16;
19 using base::android::ConvertJavaStringToUTF8;
20 using base::android::ConvertUTF16ToJavaString;
21 using base::android::ConvertUTF8ToJavaString;
25 static base::android::ScopedJavaLocalRef<jobject> CreateJavaNavigationEntry(
27 content::NavigationEntry* entry,
31 // Get the details of the current entry
32 ScopedJavaLocalRef<jstring> j_url(
33 ConvertUTF8ToJavaString(env, entry->GetURL().spec()));
34 ScopedJavaLocalRef<jstring> j_virtual_url(
35 ConvertUTF8ToJavaString(env, entry->GetVirtualURL().spec()));
36 ScopedJavaLocalRef<jstring> j_original_url(
37 ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec()));
38 ScopedJavaLocalRef<jstring> j_title(
39 ConvertUTF16ToJavaString(env, entry->GetTitle()));
40 ScopedJavaLocalRef<jobject> j_bitmap;
41 const content::FaviconStatus& status = entry->GetFavicon();
42 if (status.valid && status.image.ToSkBitmap()->getSize() > 0)
43 j_bitmap = gfx::ConvertToJavaBitmap(status.image.ToSkBitmap());
45 return content::Java_NavigationControllerImpl_createNavigationEntry(
55 static void AddNavigationEntryToHistory(JNIEnv* env,
57 content::NavigationEntry* entry,
59 content::Java_NavigationControllerImpl_addToNavigationHistory(
62 CreateJavaNavigationEntry(env, entry, index).obj());
70 bool NavigationControllerAndroid::Register(JNIEnv* env) {
71 return RegisterNativesImpl(env);
74 NavigationControllerAndroid::NavigationControllerAndroid(
75 NavigationController* navigation_controller)
76 : navigation_controller_(navigation_controller) {
77 JNIEnv* env = AttachCurrentThread();
79 Java_NavigationControllerImpl_create(
80 env, reinterpret_cast<intptr_t>(this)).obj());
83 NavigationControllerAndroid::~NavigationControllerAndroid() {
84 Java_NavigationControllerImpl_destroy(AttachCurrentThread(), obj_.obj());
87 base::android::ScopedJavaLocalRef<jobject>
88 NavigationControllerAndroid::GetJavaObject() {
89 return base::android::ScopedJavaLocalRef<jobject>(obj_);
92 jboolean NavigationControllerAndroid::CanGoBack(JNIEnv* env, jobject obj) {
93 return navigation_controller_->CanGoBack();
96 jboolean NavigationControllerAndroid::CanGoForward(JNIEnv* env,
98 return navigation_controller_->CanGoForward();
101 jboolean NavigationControllerAndroid::CanGoToOffset(JNIEnv* env,
104 return navigation_controller_->CanGoToOffset(offset);
107 void NavigationControllerAndroid::GoBack(JNIEnv* env, jobject obj) {
108 navigation_controller_->GoBack();
111 void NavigationControllerAndroid::GoForward(JNIEnv* env, jobject obj) {
112 navigation_controller_->GoForward();
115 void NavigationControllerAndroid::GoToOffset(JNIEnv* env,
118 navigation_controller_->GoToOffset(offset);
121 void NavigationControllerAndroid::LoadIfNecessary(JNIEnv* env, jobject obj) {
122 navigation_controller_->LoadIfNecessary();
125 void NavigationControllerAndroid::ContinuePendingReload(JNIEnv* env,
127 navigation_controller_->ContinuePendingReload();
130 void NavigationControllerAndroid::Reload(JNIEnv* env,
132 jboolean check_for_repost) {
133 navigation_controller_->Reload(check_for_repost);
136 void NavigationControllerAndroid::ReloadIgnoringCache(
139 jboolean check_for_repost) {
140 navigation_controller_->ReloadIgnoringCache(check_for_repost);
143 void NavigationControllerAndroid::RequestRestoreLoad(JNIEnv* env, jobject obj) {
144 navigation_controller_->SetNeedsReload();
147 void NavigationControllerAndroid::CancelPendingReload(JNIEnv* env,
149 navigation_controller_->CancelPendingReload();
152 void NavigationControllerAndroid::GoToNavigationIndex(JNIEnv* env,
155 navigation_controller_->GoToIndex(index);
158 void NavigationControllerAndroid::LoadUrl(JNIEnv* env,
162 jint transition_type,
163 jstring j_referrer_url,
164 jint referrer_policy,
165 jint ua_override_option,
166 jstring extra_headers,
167 jbyteArray post_data,
168 jstring base_url_for_data_url,
169 jstring virtual_url_for_data_url,
170 jboolean can_load_local_resources,
171 jboolean is_renderer_initiated) {
173 NavigationController::LoadURLParams params(
174 GURL(ConvertJavaStringToUTF8(env, url)));
177 static_cast<NavigationController::LoadURLType>(load_url_type);
178 params.transition_type = ui::PageTransitionFromInt(transition_type);
179 params.override_user_agent =
180 static_cast<NavigationController::UserAgentOverrideOption>(
182 params.can_load_local_resources = can_load_local_resources;
183 params.is_renderer_initiated = is_renderer_initiated;
186 params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);
189 std::vector<uint8> http_body_vector;
190 base::android::JavaByteArrayToByteVector(env, post_data, &http_body_vector);
191 params.browser_initiated_post_data =
192 base::RefCountedBytes::TakeVector(&http_body_vector);
195 if (base_url_for_data_url) {
196 params.base_url_for_data_url =
197 GURL(ConvertJavaStringToUTF8(env, base_url_for_data_url));
200 if (virtual_url_for_data_url) {
201 params.virtual_url_for_data_url =
202 GURL(ConvertJavaStringToUTF8(env, virtual_url_for_data_url));
205 if (j_referrer_url) {
206 params.referrer = content::Referrer(
207 GURL(ConvertJavaStringToUTF8(env, j_referrer_url)),
208 static_cast<blink::WebReferrerPolicy>(referrer_policy));
211 navigation_controller_->LoadURLWithParams(params);
214 void NavigationControllerAndroid::ClearHistory(JNIEnv* env, jobject obj) {
215 // TODO(creis): Do callers of this need to know if it fails?
216 if (navigation_controller_->CanPruneAllButLastCommitted())
217 navigation_controller_->PruneAllButLastCommitted();
220 jint NavigationControllerAndroid::GetNavigationHistory(JNIEnv* env,
223 // Iterate through navigation entries to populate the list
224 int count = navigation_controller_->GetEntryCount();
225 for (int i = 0; i < count; ++i) {
226 AddNavigationEntryToHistory(
227 env, history, navigation_controller_->GetEntryAtIndex(i), i);
230 return navigation_controller_->GetCurrentEntryIndex();
233 void NavigationControllerAndroid::GetDirectedNavigationHistory(
239 // Iterate through navigation entries to populate the list
240 int count = navigation_controller_->GetEntryCount();
242 int increment_value = is_forward ? 1 : -1;
243 for (int i = navigation_controller_->GetCurrentEntryIndex() + increment_value;
245 i += increment_value) {
246 if (num_added >= max_entries)
249 AddNavigationEntryToHistory(
250 env, history, navigation_controller_->GetEntryAtIndex(i), i);
255 ScopedJavaLocalRef<jstring>
256 NavigationControllerAndroid::GetOriginalUrlForVisibleNavigationEntry(
259 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
261 return ScopedJavaLocalRef<jstring>(env, NULL);
262 return ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec());
265 void NavigationControllerAndroid::ClearSslPreferences(JNIEnv* env,
267 content::SSLHostStateDelegate* delegate =
268 navigation_controller_->GetBrowserContext()->GetSSLHostStateDelegate();
273 bool NavigationControllerAndroid::GetUseDesktopUserAgent(JNIEnv* env,
275 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
276 return entry && entry->GetIsOverridingUserAgent();
279 void NavigationControllerAndroid::SetUseDesktopUserAgent(
283 jboolean reload_on_state_change) {
284 if (GetUseDesktopUserAgent(env, obj) == enabled)
287 // Make sure the navigation entry actually exists.
288 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
292 // Set the flag in the NavigationEntry.
293 entry->SetIsOverridingUserAgent(enabled);
295 // Send the override to the renderer.
296 if (reload_on_state_change) {
297 // Reloading the page will send the override down as part of the
298 // navigation IPC message.
299 navigation_controller_->ReloadOriginalRequestURL(false);
303 base::android::ScopedJavaLocalRef<jobject>
304 NavigationControllerAndroid::GetPendingEntry(JNIEnv* env, jobject obj) {
305 content::NavigationEntry* entry = navigation_controller_->GetPendingEntry();
308 return base::android::ScopedJavaLocalRef<jobject>();
310 return CreateJavaNavigationEntry(
311 env, entry, navigation_controller_->GetPendingEntryIndex());
314 jint NavigationControllerAndroid::GetLastCommittedEntryIndex(JNIEnv* env,
316 return navigation_controller_->GetLastCommittedEntryIndex();
319 jboolean NavigationControllerAndroid::RemoveEntryAtIndex(JNIEnv* env,
322 return navigation_controller_->RemoveEntryAtIndex(index);
325 } // namespace content