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(
53 entry
->GetTransitionType());
56 static void AddNavigationEntryToHistory(JNIEnv
* env
,
58 content::NavigationEntry
* entry
,
60 content::Java_NavigationControllerImpl_addToNavigationHistory(
63 CreateJavaNavigationEntry(env
, entry
, index
).obj());
71 bool NavigationControllerAndroid::Register(JNIEnv
* env
) {
72 return RegisterNativesImpl(env
);
75 NavigationControllerAndroid::NavigationControllerAndroid(
76 NavigationController
* navigation_controller
)
77 : navigation_controller_(navigation_controller
) {
78 JNIEnv
* env
= AttachCurrentThread();
80 Java_NavigationControllerImpl_create(
81 env
, reinterpret_cast<intptr_t>(this)).obj());
84 NavigationControllerAndroid::~NavigationControllerAndroid() {
85 Java_NavigationControllerImpl_destroy(AttachCurrentThread(), obj_
.obj());
88 base::android::ScopedJavaLocalRef
<jobject
>
89 NavigationControllerAndroid::GetJavaObject() {
90 return base::android::ScopedJavaLocalRef
<jobject
>(obj_
);
93 jboolean
NavigationControllerAndroid::CanGoBack(JNIEnv
* env
, jobject obj
) {
94 return navigation_controller_
->CanGoBack();
97 jboolean
NavigationControllerAndroid::CanGoForward(JNIEnv
* env
,
99 return navigation_controller_
->CanGoForward();
102 jboolean
NavigationControllerAndroid::CanGoToOffset(JNIEnv
* env
,
105 return navigation_controller_
->CanGoToOffset(offset
);
108 void NavigationControllerAndroid::GoBack(JNIEnv
* env
, jobject obj
) {
109 navigation_controller_
->GoBack();
112 void NavigationControllerAndroid::GoForward(JNIEnv
* env
, jobject obj
) {
113 navigation_controller_
->GoForward();
116 void NavigationControllerAndroid::GoToOffset(JNIEnv
* env
,
119 navigation_controller_
->GoToOffset(offset
);
122 jboolean
NavigationControllerAndroid::IsInitialNavigation(JNIEnv
* env
,
124 return navigation_controller_
->IsInitialNavigation();
127 void NavigationControllerAndroid::LoadIfNecessary(JNIEnv
* env
, jobject obj
) {
128 navigation_controller_
->LoadIfNecessary();
131 void NavigationControllerAndroid::ContinuePendingReload(JNIEnv
* env
,
133 navigation_controller_
->ContinuePendingReload();
136 void NavigationControllerAndroid::Reload(JNIEnv
* env
,
138 jboolean check_for_repost
) {
139 navigation_controller_
->Reload(check_for_repost
);
142 void NavigationControllerAndroid::ReloadIgnoringCache(
145 jboolean check_for_repost
) {
146 navigation_controller_
->ReloadIgnoringCache(check_for_repost
);
149 void NavigationControllerAndroid::RequestRestoreLoad(JNIEnv
* env
, jobject obj
) {
150 navigation_controller_
->SetNeedsReload();
153 void NavigationControllerAndroid::CancelPendingReload(JNIEnv
* env
,
155 navigation_controller_
->CancelPendingReload();
158 void NavigationControllerAndroid::GoToNavigationIndex(JNIEnv
* env
,
161 navigation_controller_
->GoToIndex(index
);
164 void NavigationControllerAndroid::LoadUrl(
169 jint transition_type
,
170 jstring j_referrer_url
,
171 jint referrer_policy
,
172 jint ua_override_option
,
173 jstring extra_headers
,
174 jbyteArray post_data
,
175 jstring base_url_for_data_url
,
176 jstring virtual_url_for_data_url
,
177 jboolean can_load_local_resources
,
178 jboolean is_renderer_initiated
,
179 jboolean should_replace_current_entry
) {
181 NavigationController::LoadURLParams
params(
182 GURL(ConvertJavaStringToUTF8(env
, url
)));
185 static_cast<NavigationController::LoadURLType
>(load_url_type
);
186 params
.transition_type
= ui::PageTransitionFromInt(transition_type
);
187 params
.override_user_agent
=
188 static_cast<NavigationController::UserAgentOverrideOption
>(
190 params
.can_load_local_resources
= can_load_local_resources
;
191 params
.is_renderer_initiated
= is_renderer_initiated
;
192 params
.should_replace_current_entry
= should_replace_current_entry
;
195 params
.extra_headers
= ConvertJavaStringToUTF8(env
, extra_headers
);
198 std::vector
<uint8
> http_body_vector
;
199 base::android::JavaByteArrayToByteVector(env
, post_data
, &http_body_vector
);
200 params
.browser_initiated_post_data
=
201 base::RefCountedBytes::TakeVector(&http_body_vector
);
204 if (base_url_for_data_url
) {
205 params
.base_url_for_data_url
=
206 GURL(ConvertJavaStringToUTF8(env
, base_url_for_data_url
));
209 if (virtual_url_for_data_url
) {
210 params
.virtual_url_for_data_url
=
211 GURL(ConvertJavaStringToUTF8(env
, virtual_url_for_data_url
));
214 if (j_referrer_url
) {
215 params
.referrer
= content::Referrer(
216 GURL(ConvertJavaStringToUTF8(env
, j_referrer_url
)),
217 static_cast<blink::WebReferrerPolicy
>(referrer_policy
));
220 navigation_controller_
->LoadURLWithParams(params
);
223 void NavigationControllerAndroid::ClearHistory(JNIEnv
* env
, jobject obj
) {
224 // TODO(creis): Do callers of this need to know if it fails?
225 if (navigation_controller_
->CanPruneAllButLastCommitted())
226 navigation_controller_
->PruneAllButLastCommitted();
229 jint
NavigationControllerAndroid::GetNavigationHistory(JNIEnv
* env
,
232 // Iterate through navigation entries to populate the list
233 int count
= navigation_controller_
->GetEntryCount();
234 for (int i
= 0; i
< count
; ++i
) {
235 AddNavigationEntryToHistory(
236 env
, history
, navigation_controller_
->GetEntryAtIndex(i
), i
);
239 return navigation_controller_
->GetCurrentEntryIndex();
242 void NavigationControllerAndroid::GetDirectedNavigationHistory(
248 // Iterate through navigation entries to populate the list
249 int count
= navigation_controller_
->GetEntryCount();
251 int increment_value
= is_forward
? 1 : -1;
252 for (int i
= navigation_controller_
->GetCurrentEntryIndex() + increment_value
;
254 i
+= increment_value
) {
255 if (num_added
>= max_entries
)
258 AddNavigationEntryToHistory(
259 env
, history
, navigation_controller_
->GetEntryAtIndex(i
), i
);
264 ScopedJavaLocalRef
<jstring
>
265 NavigationControllerAndroid::GetOriginalUrlForVisibleNavigationEntry(
268 NavigationEntry
* entry
= navigation_controller_
->GetVisibleEntry();
270 return ScopedJavaLocalRef
<jstring
>(env
, NULL
);
271 return ConvertUTF8ToJavaString(env
, entry
->GetOriginalRequestURL().spec());
274 void NavigationControllerAndroid::ClearSslPreferences(JNIEnv
* env
,
276 content::SSLHostStateDelegate
* delegate
=
277 navigation_controller_
->GetBrowserContext()->GetSSLHostStateDelegate();
282 bool NavigationControllerAndroid::GetUseDesktopUserAgent(JNIEnv
* env
,
284 NavigationEntry
* entry
= navigation_controller_
->GetVisibleEntry();
285 return entry
&& entry
->GetIsOverridingUserAgent();
288 void NavigationControllerAndroid::SetUseDesktopUserAgent(
292 jboolean reload_on_state_change
) {
293 if (GetUseDesktopUserAgent(env
, obj
) == enabled
)
296 // Make sure the navigation entry actually exists.
297 NavigationEntry
* entry
= navigation_controller_
->GetVisibleEntry();
301 // Set the flag in the NavigationEntry.
302 entry
->SetIsOverridingUserAgent(enabled
);
304 // Send the override to the renderer.
305 if (reload_on_state_change
) {
306 // Reloading the page will send the override down as part of the
307 // navigation IPC message.
308 navigation_controller_
->ReloadOriginalRequestURL(false);
312 base::android::ScopedJavaLocalRef
<jobject
>
313 NavigationControllerAndroid::GetEntryAtIndex(JNIEnv
* env
,
316 if (index
< 0 || index
>= navigation_controller_
->GetEntryCount())
317 return base::android::ScopedJavaLocalRef
<jobject
>();
319 content::NavigationEntry
* entry
=
320 navigation_controller_
->GetEntryAtIndex(index
);
321 return CreateJavaNavigationEntry(env
, entry
, index
);
324 base::android::ScopedJavaLocalRef
<jobject
>
325 NavigationControllerAndroid::GetPendingEntry(JNIEnv
* env
, jobject obj
) {
326 content::NavigationEntry
* entry
= navigation_controller_
->GetPendingEntry();
329 return base::android::ScopedJavaLocalRef
<jobject
>();
331 return CreateJavaNavigationEntry(
332 env
, entry
, navigation_controller_
->GetPendingEntryIndex());
335 jint
NavigationControllerAndroid::GetLastCommittedEntryIndex(JNIEnv
* env
,
337 return navigation_controller_
->GetLastCommittedEntryIndex();
340 jboolean
NavigationControllerAndroid::RemoveEntryAtIndex(JNIEnv
* env
,
343 return navigation_controller_
->RemoveEntryAtIndex(index
);
346 jboolean
NavigationControllerAndroid::CanCopyStateOver(JNIEnv
* env
,
348 return navigation_controller_
->GetEntryCount() == 0 &&
349 !navigation_controller_
->GetPendingEntry();
352 jboolean
NavigationControllerAndroid::CanPruneAllButLastCommitted(JNIEnv
* env
,
354 return navigation_controller_
->CanPruneAllButLastCommitted();
357 void NavigationControllerAndroid::CopyStateFrom(
360 jlong source_navigation_controller_android
) {
361 navigation_controller_
->CopyStateFrom(
362 *(reinterpret_cast<NavigationControllerAndroid
*>(
363 source_navigation_controller_android
)->navigation_controller_
));
366 void NavigationControllerAndroid::CopyStateFromAndPrune(
369 jlong source_navigation_controller_android
,
370 jboolean replace_entry
) {
371 navigation_controller_
->CopyStateFromAndPrune(
372 reinterpret_cast<NavigationControllerAndroid
*>(
373 source_navigation_controller_android
)->navigation_controller_
,
377 } // namespace content