blob: 42b86e51087f045e5f24f26b2fa2e52ddee9cd1b [file] [log] [blame]
[email protected]155c7f22013-12-09 17:07:181// 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 "content/browser/frame_host/navigation_controller_android.h"
6
avib7348942015-12-25 20:57:107#include <stdint.h>
8
[email protected]155c7f22013-12-09 17:07:189#include "base/android/jni_android.h"
ajith.v4502cc62014-09-05 17:41:3910#include "base/android/jni_string.h"
msrameke7da2982016-09-07 09:58:0811#include "base/callback.h"
aelias5252baa2016-04-10 01:18:0212#include "content/browser/frame_host/navigation_controller_impl.h"
ajith.v4502cc62014-09-05 17:41:3913#include "content/browser/frame_host/navigation_entry_impl.h"
14#include "content/public/browser/browser_context.h"
ajith.v4502cc62014-09-05 17:41:3915#include "content/public/browser/ssl_host_state_delegate.h"
lukasza477a5a22016-06-16 18:28:4316#include "content/public/common/resource_request_body.h"
[email protected]155c7f22013-12-09 17:07:1817#include "jni/NavigationControllerImpl_jni.h"
mnaganovbf087422015-12-16 05:10:0318#include "net/base/data_url.h"
ajith.v4502cc62014-09-05 17:41:3919#include "ui/gfx/android/java_bitmap.h"
[email protected]155c7f22013-12-09 17:07:1820
21using base::android::AttachCurrentThread;
ajith.v4502cc62014-09-05 17:41:3922using base::android::ConvertJavaStringToUTF16;
23using base::android::ConvertJavaStringToUTF8;
24using base::android::ConvertUTF16ToJavaString;
25using base::android::ConvertUTF8ToJavaString;
torne86560112016-08-04 15:59:0426using base::android::JavaParamRef;
27using base::android::ScopedJavaLocalRef;
ajith.v4502cc62014-09-05 17:41:3928namespace {
29
30// static
dtrainorb316e9272014-09-19 23:30:5531static base::android::ScopedJavaLocalRef<jobject> CreateJavaNavigationEntry(
32 JNIEnv* env,
33 content::NavigationEntry* entry,
34 int index) {
35 DCHECK(entry);
36
ajith.v4502cc62014-09-05 17:41:3937 // Get the details of the current entry
38 ScopedJavaLocalRef<jstring> j_url(
39 ConvertUTF8ToJavaString(env, entry->GetURL().spec()));
40 ScopedJavaLocalRef<jstring> j_virtual_url(
41 ConvertUTF8ToJavaString(env, entry->GetVirtualURL().spec()));
42 ScopedJavaLocalRef<jstring> j_original_url(
43 ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec()));
44 ScopedJavaLocalRef<jstring> j_title(
45 ConvertUTF16ToJavaString(env, entry->GetTitle()));
46 ScopedJavaLocalRef<jobject> j_bitmap;
47 const content::FaviconStatus& status = entry->GetFavicon();
48 if (status.valid && status.image.ToSkBitmap()->getSize() > 0)
49 j_bitmap = gfx::ConvertToJavaBitmap(status.image.ToSkBitmap());
50
dtrainorb316e9272014-09-19 23:30:5551 return content::Java_NavigationControllerImpl_createNavigationEntry(
torne948f3662016-08-16 15:10:4452 env, index, j_url, j_virtual_url, j_original_url, j_title, j_bitmap,
mnaganov7a3234c2015-03-23 21:28:5953 entry->GetTransitionType());
ajith.v4502cc62014-09-05 17:41:3954}
55
dtrainorb316e9272014-09-19 23:30:5556static void AddNavigationEntryToHistory(JNIEnv* env,
57 jobject history,
58 content::NavigationEntry* entry,
59 int index) {
60 content::Java_NavigationControllerImpl_addToNavigationHistory(
torne948f3662016-08-16 15:10:4461 env, history, CreateJavaNavigationEntry(env, entry, index));
dtrainorb316e9272014-09-19 23:30:5562}
63
ajith.v4502cc62014-09-05 17:41:3964} // namespace
[email protected]155c7f22013-12-09 17:07:1865
66namespace content {
67
68// static
69bool NavigationControllerAndroid::Register(JNIEnv* env) {
70 return RegisterNativesImpl(env);
71}
72
73NavigationControllerAndroid::NavigationControllerAndroid(
aelias5252baa2016-04-10 01:18:0274 NavigationControllerImpl* navigation_controller)
[email protected]155c7f22013-12-09 17:07:1875 : navigation_controller_(navigation_controller) {
76 JNIEnv* env = AttachCurrentThread();
77 obj_.Reset(env,
78 Java_NavigationControllerImpl_create(
79 env, reinterpret_cast<intptr_t>(this)).obj());
80}
81
82NavigationControllerAndroid::~NavigationControllerAndroid() {
torne948f3662016-08-16 15:10:4483 Java_NavigationControllerImpl_destroy(AttachCurrentThread(), obj_);
[email protected]155c7f22013-12-09 17:07:1884}
85
86base::android::ScopedJavaLocalRef<jobject>
87NavigationControllerAndroid::GetJavaObject() {
88 return base::android::ScopedJavaLocalRef<jobject>(obj_);
89}
90
tornee1bfee92015-12-01 14:05:0191jboolean NavigationControllerAndroid::CanGoBack(
92 JNIEnv* env,
93 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:1894 return navigation_controller_->CanGoBack();
95}
96
tornee1bfee92015-12-01 14:05:0197jboolean NavigationControllerAndroid::CanGoForward(
98 JNIEnv* env,
99 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18100 return navigation_controller_->CanGoForward();
101}
102
tornee1bfee92015-12-01 14:05:01103jboolean NavigationControllerAndroid::CanGoToOffset(
104 JNIEnv* env,
105 const JavaParamRef<jobject>& obj,
106 jint offset) {
[email protected]155c7f22013-12-09 17:07:18107 return navigation_controller_->CanGoToOffset(offset);
108}
109
tornee1bfee92015-12-01 14:05:01110void NavigationControllerAndroid::GoBack(JNIEnv* env,
111 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18112 navigation_controller_->GoBack();
113}
114
tornee1bfee92015-12-01 14:05:01115void NavigationControllerAndroid::GoForward(JNIEnv* env,
116 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18117 navigation_controller_->GoForward();
118}
119
120void NavigationControllerAndroid::GoToOffset(JNIEnv* env,
tornee1bfee92015-12-01 14:05:01121 const JavaParamRef<jobject>& obj,
[email protected]155c7f22013-12-09 17:07:18122 jint offset) {
123 navigation_controller_->GoToOffset(offset);
124}
125
tornee1bfee92015-12-01 14:05:01126jboolean NavigationControllerAndroid::IsInitialNavigation(
127 JNIEnv* env,
128 const JavaParamRef<jobject>& obj) {
dfalcantara0d314d522015-01-05 22:56:43129 return navigation_controller_->IsInitialNavigation();
130}
131
tornee1bfee92015-12-01 14:05:01132void NavigationControllerAndroid::LoadIfNecessary(
133 JNIEnv* env,
134 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29135 navigation_controller_->LoadIfNecessary();
136}
137
tornee1bfee92015-12-01 14:05:01138void NavigationControllerAndroid::ContinuePendingReload(
139 JNIEnv* env,
140 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29141 navigation_controller_->ContinuePendingReload();
142}
143
144void NavigationControllerAndroid::Reload(JNIEnv* env,
tornee1bfee92015-12-01 14:05:01145 const JavaParamRef<jobject>& obj,
[email protected]6d3f32f2014-07-08 08:23:29146 jboolean check_for_repost) {
147 navigation_controller_->Reload(check_for_repost);
148}
149
kinuko1be5023c2015-12-16 02:31:57150void NavigationControllerAndroid::ReloadToRefreshContent(
151 JNIEnv* env,
152 jobject obj,
153 jboolean check_for_repost) {
154 navigation_controller_->ReloadToRefreshContent(check_for_repost);
155}
156
toyoshim7dad4b1182016-04-01 14:28:05157void NavigationControllerAndroid::ReloadBypassingCache(
[email protected]6d3f32f2014-07-08 08:23:29158 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01159 const JavaParamRef<jobject>& obj,
[email protected]6d3f32f2014-07-08 08:23:29160 jboolean check_for_repost) {
toyoshim7dad4b1182016-04-01 14:28:05161 navigation_controller_->ReloadBypassingCache(check_for_repost);
[email protected]6d3f32f2014-07-08 08:23:29162}
163
megjablon39a903082015-10-26 23:36:29164void NavigationControllerAndroid::ReloadDisableLoFi(
165 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01166 const JavaParamRef<jobject>& obj,
megjablon39a903082015-10-26 23:36:29167 jboolean check_for_repost) {
168 navigation_controller_->ReloadDisableLoFi(check_for_repost);
169}
170
tornee1bfee92015-12-01 14:05:01171void NavigationControllerAndroid::RequestRestoreLoad(
172 JNIEnv* env,
173 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29174 navigation_controller_->SetNeedsReload();
175}
176
tornee1bfee92015-12-01 14:05:01177void NavigationControllerAndroid::CancelPendingReload(
178 JNIEnv* env,
179 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29180 navigation_controller_->CancelPendingReload();
181}
182
tornee1bfee92015-12-01 14:05:01183void NavigationControllerAndroid::GoToNavigationIndex(
184 JNIEnv* env,
185 const JavaParamRef<jobject>& obj,
186 jint index) {
[email protected]155c7f22013-12-09 17:07:18187 navigation_controller_->GoToIndex(index);
188}
189
lizebe8adeb82015-08-20 12:18:10190void NavigationControllerAndroid::LoadUrl(
191 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01192 const JavaParamRef<jobject>& obj,
193 const JavaParamRef<jstring>& url,
lizebe8adeb82015-08-20 12:18:10194 jint load_url_type,
195 jint transition_type,
tornee1bfee92015-12-01 14:05:01196 const JavaParamRef<jstring>& j_referrer_url,
lizebe8adeb82015-08-20 12:18:10197 jint referrer_policy,
198 jint ua_override_option,
tornee1bfee92015-12-01 14:05:01199 const JavaParamRef<jstring>& extra_headers,
lukasza477a5a22016-06-16 18:28:43200 const JavaParamRef<jobject>& j_post_data,
tornee1bfee92015-12-01 14:05:01201 const JavaParamRef<jstring>& base_url_for_data_url,
202 const JavaParamRef<jstring>& virtual_url_for_data_url,
mnaganovbf087422015-12-16 05:10:03203 const JavaParamRef<jstring>& data_url_as_string,
lizebe8adeb82015-08-20 12:18:10204 jboolean can_load_local_resources,
205 jboolean is_renderer_initiated,
206 jboolean should_replace_current_entry) {
ajith.v4502cc62014-09-05 17:41:39207 DCHECK(url);
208 NavigationController::LoadURLParams params(
209 GURL(ConvertJavaStringToUTF8(env, url)));
210
211 params.load_type =
212 static_cast<NavigationController::LoadURLType>(load_url_type);
Sylvain Defresnec6ccc77d2014-09-19 10:19:35213 params.transition_type = ui::PageTransitionFromInt(transition_type);
ajith.v4502cc62014-09-05 17:41:39214 params.override_user_agent =
215 static_cast<NavigationController::UserAgentOverrideOption>(
216 ua_override_option);
217 params.can_load_local_resources = can_load_local_resources;
218 params.is_renderer_initiated = is_renderer_initiated;
lizebe8adeb82015-08-20 12:18:10219 params.should_replace_current_entry = should_replace_current_entry;
ajith.v4502cc62014-09-05 17:41:39220
221 if (extra_headers)
222 params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);
223
lukasza477a5a22016-06-16 18:28:43224 params.post_data = ResourceRequestBody::FromJavaObject(env, j_post_data);
ajith.v4502cc62014-09-05 17:41:39225
226 if (base_url_for_data_url) {
227 params.base_url_for_data_url =
228 GURL(ConvertJavaStringToUTF8(env, base_url_for_data_url));
229 }
230
231 if (virtual_url_for_data_url) {
232 params.virtual_url_for_data_url =
233 GURL(ConvertJavaStringToUTF8(env, virtual_url_for_data_url));
234 }
235
mnaganovbf087422015-12-16 05:10:03236 if (data_url_as_string) {
237 // Treat |data_url_as_string| as if we were intending to put it into a GURL
238 // field. Note that kMaxURLChars is only enforced when serializing URLs
239 // for IPC.
240 GURL data_url = GURL(ConvertJavaStringToUTF8(env, data_url_as_string));
241 DCHECK(data_url.SchemeIs(url::kDataScheme));
242 DCHECK(params.url.SchemeIs(url::kDataScheme));
243#if DCHECK_IS_ON()
244 {
245 std::string mime_type, charset, data;
246 DCHECK(net::DataURL::Parse(params.url, &mime_type, &charset, &data));
247 DCHECK(data.empty());
248 }
249#endif
250 std::string s = data_url.spec();
251 params.data_url_as_string = base::RefCountedString::TakeString(&s);
252 }
253
ajith.v4502cc62014-09-05 17:41:39254 if (j_referrer_url) {
255 params.referrer = content::Referrer(
256 GURL(ConvertJavaStringToUTF8(env, j_referrer_url)),
257 static_cast<blink::WebReferrerPolicy>(referrer_policy));
258 }
259
260 navigation_controller_->LoadURLWithParams(params);
261}
262
tornee1bfee92015-12-01 14:05:01263void NavigationControllerAndroid::ClearHistory(
264 JNIEnv* env,
265 const JavaParamRef<jobject>& obj) {
ajith.v4502cc62014-09-05 17:41:39266 // TODO(creis): Do callers of this need to know if it fails?
267 if (navigation_controller_->CanPruneAllButLastCommitted())
268 navigation_controller_->PruneAllButLastCommitted();
269}
270
tornee1bfee92015-12-01 14:05:01271jint NavigationControllerAndroid::GetNavigationHistory(
272 JNIEnv* env,
273 const JavaParamRef<jobject>& obj,
274 const JavaParamRef<jobject>& history) {
ajith.v4502cc62014-09-05 17:41:39275 // Iterate through navigation entries to populate the list
276 int count = navigation_controller_->GetEntryCount();
277 for (int i = 0; i < count; ++i) {
278 AddNavigationEntryToHistory(
dtrainorb316e9272014-09-19 23:30:55279 env, history, navigation_controller_->GetEntryAtIndex(i), i);
ajith.v4502cc62014-09-05 17:41:39280 }
281
282 return navigation_controller_->GetCurrentEntryIndex();
283}
284
285void NavigationControllerAndroid::GetDirectedNavigationHistory(
286 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01287 const JavaParamRef<jobject>& obj,
288 const JavaParamRef<jobject>& history,
ajith.v4502cc62014-09-05 17:41:39289 jboolean is_forward,
290 jint max_entries) {
291 // Iterate through navigation entries to populate the list
292 int count = navigation_controller_->GetEntryCount();
293 int num_added = 0;
294 int increment_value = is_forward ? 1 : -1;
295 for (int i = navigation_controller_->GetCurrentEntryIndex() + increment_value;
296 i >= 0 && i < count;
297 i += increment_value) {
298 if (num_added >= max_entries)
299 break;
300
301 AddNavigationEntryToHistory(
dtrainorb316e9272014-09-19 23:30:55302 env, history, navigation_controller_->GetEntryAtIndex(i), i);
ajith.v4502cc62014-09-05 17:41:39303 num_added++;
304 }
305}
306
307ScopedJavaLocalRef<jstring>
308NavigationControllerAndroid::GetOriginalUrlForVisibleNavigationEntry(
309 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01310 const JavaParamRef<jobject>& obj) {
ajith.v4502cc62014-09-05 17:41:39311 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
312 if (entry == NULL)
313 return ScopedJavaLocalRef<jstring>(env, NULL);
314 return ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec());
315}
316
tornee1bfee92015-12-01 14:05:01317void NavigationControllerAndroid::ClearSslPreferences(
318 JNIEnv* env,
319 const JavaParamRef<jobject>& obj) {
ajith.v4502cc62014-09-05 17:41:39320 content::SSLHostStateDelegate* delegate =
321 navigation_controller_->GetBrowserContext()->GetSSLHostStateDelegate();
322 if (delegate)
msrameke7da2982016-09-07 09:58:08323 delegate->Clear(base::Callback<bool(const std::string&)>());
ajith.v4502cc62014-09-05 17:41:39324}
325
tornee1bfee92015-12-01 14:05:01326bool NavigationControllerAndroid::GetUseDesktopUserAgent(
327 JNIEnv* env,
328 const JavaParamRef<jobject>& obj) {
ajith.v4502cc62014-09-05 17:41:39329 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
330 return entry && entry->GetIsOverridingUserAgent();
331}
332
333void NavigationControllerAndroid::SetUseDesktopUserAgent(
334 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01335 const JavaParamRef<jobject>& obj,
ajith.v4502cc62014-09-05 17:41:39336 jboolean enabled,
337 jboolean reload_on_state_change) {
338 if (GetUseDesktopUserAgent(env, obj) == enabled)
339 return;
340
341 // Make sure the navigation entry actually exists.
342 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
343 if (!entry)
344 return;
345
346 // Set the flag in the NavigationEntry.
347 entry->SetIsOverridingUserAgent(enabled);
aelias5252baa2016-04-10 01:18:02348 navigation_controller_->delegate()->UpdateOverridingUserAgent();
ajith.v4502cc62014-09-05 17:41:39349
350 // Send the override to the renderer.
351 if (reload_on_state_change) {
352 // Reloading the page will send the override down as part of the
353 // navigation IPC message.
354 navigation_controller_->ReloadOriginalRequestURL(false);
355 }
356}
357
dtrainorb316e9272014-09-19 23:30:55358base::android::ScopedJavaLocalRef<jobject>
dfalcantaraf5d7ff812015-01-16 22:58:03359NavigationControllerAndroid::GetEntryAtIndex(JNIEnv* env,
tornee1bfee92015-12-01 14:05:01360 const JavaParamRef<jobject>& obj,
dfalcantaraf5d7ff812015-01-16 22:58:03361 int index) {
362 if (index < 0 || index >= navigation_controller_->GetEntryCount())
363 return base::android::ScopedJavaLocalRef<jobject>();
364
365 content::NavigationEntry* entry =
366 navigation_controller_->GetEntryAtIndex(index);
367 return CreateJavaNavigationEntry(env, entry, index);
368}
369
370base::android::ScopedJavaLocalRef<jobject>
tornee1bfee92015-12-01 14:05:01371NavigationControllerAndroid::GetPendingEntry(JNIEnv* env,
372 const JavaParamRef<jobject>& obj) {
dtrainorb316e9272014-09-19 23:30:55373 content::NavigationEntry* entry = navigation_controller_->GetPendingEntry();
374
375 if (!entry)
376 return base::android::ScopedJavaLocalRef<jobject>();
377
378 return CreateJavaNavigationEntry(
379 env, entry, navigation_controller_->GetPendingEntryIndex());
380}
381
tornee1bfee92015-12-01 14:05:01382jint NavigationControllerAndroid::GetLastCommittedEntryIndex(
383 JNIEnv* env,
384 const JavaParamRef<jobject>& obj) {
jaekyun45bc8c52014-11-03 01:00:21385 return navigation_controller_->GetLastCommittedEntryIndex();
386}
387
tornee1bfee92015-12-01 14:05:01388jboolean NavigationControllerAndroid::RemoveEntryAtIndex(
389 JNIEnv* env,
390 const JavaParamRef<jobject>& obj,
391 jint index) {
jaekyun45bc8c52014-11-03 01:00:21392 return navigation_controller_->RemoveEntryAtIndex(index);
393}
394
tornee1bfee92015-12-01 14:05:01395jboolean NavigationControllerAndroid::CanCopyStateOver(
396 JNIEnv* env,
397 const JavaParamRef<jobject>& obj) {
aruslanb47a7a32015-06-04 03:11:08398 return navigation_controller_->GetEntryCount() == 0 &&
399 !navigation_controller_->GetPendingEntry();
400}
401
tornee1bfee92015-12-01 14:05:01402jboolean NavigationControllerAndroid::CanPruneAllButLastCommitted(
403 JNIEnv* env,
404 const JavaParamRef<jobject>& obj) {
aruslanb47a7a32015-06-04 03:11:08405 return navigation_controller_->CanPruneAllButLastCommitted();
406}
407
408void NavigationControllerAndroid::CopyStateFrom(
409 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01410 const JavaParamRef<jobject>& obj,
aruslanb47a7a32015-06-04 03:11:08411 jlong source_navigation_controller_android) {
412 navigation_controller_->CopyStateFrom(
413 *(reinterpret_cast<NavigationControllerAndroid*>(
414 source_navigation_controller_android)->navigation_controller_));
415}
416
417void NavigationControllerAndroid::CopyStateFromAndPrune(
418 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01419 const JavaParamRef<jobject>& obj,
aruslanb47a7a32015-06-04 03:11:08420 jlong source_navigation_controller_android,
421 jboolean replace_entry) {
422 navigation_controller_->CopyStateFromAndPrune(
423 reinterpret_cast<NavigationControllerAndroid*>(
424 source_navigation_controller_android)->navigation_controller_,
425 replace_entry);
426}
427
[email protected]155c7f22013-12-09 17:07:18428} // namespace content