blob: f3d19d1e67127e59c4bf468afc0e54a90fdf68e4 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
[email protected]155c7f22013-12-09 17:07:182// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakjc492bf82020-09-09 20:02:445#include "content/browser/renderer_host/navigation_controller_android.h"
[email protected]155c7f22013-12-09 17:07:186
avib7348942015-12-25 20:57:107#include <stdint.h>
8
Jan Wilken Dörriead587c32021-03-11 14:09:279#include <string>
10
[email protected]155c7f22013-12-09 17:07:1811#include "base/android/jni_android.h"
ajith.v4502cc62014-09-05 17:41:3912#include "base/android/jni_string.h"
Scott Violetf4eec902019-04-04 21:20:3413#include "base/containers/flat_map.h"
Rakina Zata Amnid605d462022-06-01 10:17:0314#include "base/debug/crash_logging.h"
Rakina Zata Amni148dcad72022-06-08 14:53:5015#include "base/debug/dump_without_crashing.h"
Avi Drissmanadac21992023-01-11 23:46:3916#include "base/functional/callback.h"
17#include "base/functional/callback_helpers.h"
John Delaney43de85fd62023-05-24 17:31:3918#include "content/browser/android/impression_utils.h"
danakjc492bf82020-09-09 20:02:4419#include "content/browser/renderer_host/navigation_controller_impl.h"
20#include "content/browser/renderer_host/navigation_entry_impl.h"
Mohamed Heikalc09e1012019-06-21 14:47:2621#include "content/public/android/content_jni_headers/NavigationControllerImpl_jni.h"
ajith.v4502cc62014-09-05 17:41:3922#include "content/public/browser/browser_context.h"
Lei Zhang589ef702022-08-26 19:38:0423#include "content/public/browser/browser_task_traits.h"
24#include "content/public/browser/browser_thread.h"
Pete Williamson1d87f4622022-10-18 19:36:4325#include "content/public/browser/navigation_handle.h"
ajith.v4502cc62014-09-05 17:41:3926#include "content/public/browser/ssl_host_state_delegate.h"
Lukasz Anforowicza192eb952019-10-15 19:22:2227#include "content/public/common/referrer.h"
John Abd-El-Maleka59411632018-01-10 20:08:2828#include "content/public/common/resource_request_body_android.h"
Michael Thiessend9fc0662021-06-22 22:29:1829#include "content/public/common/url_constants.h"
mnaganovbf087422015-12-16 05:10:0330#include "net/base/data_url.h"
ajith.v4502cc62014-09-05 17:41:3931#include "ui/gfx/android/java_bitmap.h"
Yaron Friedman09b9c5972020-12-15 17:47:3932#include "url/android/gurl_android.h"
Michael Thiessend3c9a032021-04-19 17:01:3733#include "url/gurl.h"
34#include "url/origin.h"
[email protected]155c7f22013-12-09 17:07:1835
36using base::android::AttachCurrentThread;
ajith.v4502cc62014-09-05 17:41:3937using base::android::ConvertJavaStringToUTF16;
38using base::android::ConvertJavaStringToUTF8;
39using base::android::ConvertUTF16ToJavaString;
torne86560112016-08-04 15:59:0440using base::android::JavaParamRef;
torne660061cd2016-09-07 17:47:5441using base::android::JavaRef;
torne86560112016-08-04 15:59:0442using base::android::ScopedJavaLocalRef;
torne660061cd2016-09-07 17:47:5443
ajith.v4502cc62014-09-05 17:41:3944namespace {
45
Scott Violetf4eec902019-04-04 21:20:3446const char kMapDataKey[] = "map_data_key";
47
ajith.v4502cc62014-09-05 17:41:3948// static
Daniel Bratell7aacf952017-11-21 17:51:2549static base::android::ScopedJavaLocalRef<jobject>
50JNI_NavigationControllerImpl_CreateJavaNavigationEntry(
dtrainorb316e9272014-09-19 23:30:5551 JNIEnv* env,
52 content::NavigationEntry* entry,
53 int index) {
54 DCHECK(entry);
55
ajith.v4502cc62014-09-05 17:41:3956 // Get the details of the current entry
Yaron Friedman09b9c5972020-12-15 17:47:3957 ScopedJavaLocalRef<jobject> j_url(
58 url::GURLAndroid::FromNativeGURL(env, entry->GetURL()));
59 ScopedJavaLocalRef<jobject> j_virtual_url(
60 url::GURLAndroid::FromNativeGURL(env, entry->GetVirtualURL()));
61 ScopedJavaLocalRef<jobject> j_original_url(
62 url::GURLAndroid::FromNativeGURL(env, entry->GetOriginalRequestURL()));
ajith.v4502cc62014-09-05 17:41:3963 ScopedJavaLocalRef<jstring> j_title(
64 ConvertUTF16ToJavaString(env, entry->GetTitle()));
65 ScopedJavaLocalRef<jobject> j_bitmap;
66 const content::FaviconStatus& status = entry->GetFavicon();
Rulong Chen(陈汝龙)61e3cc822020-08-29 03:29:2567 if (status.valid && status.image.ToSkBitmap()->computeByteSize() > 0) {
danakj5cc14ce2020-11-10 22:00:4068 j_bitmap = gfx::ConvertToJavaBitmap(*status.image.ToSkBitmap(),
Rulong Chen(陈汝龙)61e3cc822020-08-29 03:29:2569 gfx::OomBehavior::kReturnNullOnOom);
70 }
Jeffrey Cohen23f8cd772019-03-19 17:17:2871 jlong j_timestamp = entry->GetTimestamp().ToJavaTime();
ajith.v4502cc62014-09-05 17:41:3972
dtrainorb316e9272014-09-19 23:30:5573 return content::Java_NavigationControllerImpl_createNavigationEntry(
Yaron Friedmanf381f132022-11-29 21:47:4074 env, index, j_url, j_virtual_url, j_original_url, j_title, j_bitmap,
75 entry->GetTransitionType(), j_timestamp, entry->IsInitialEntry());
ajith.v4502cc62014-09-05 17:41:3976}
77
Daniel Bratell7aacf952017-11-21 17:51:2578static void JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
79 JNIEnv* env,
80 const JavaRef<jobject>& history,
81 content::NavigationEntry* entry,
82 int index) {
dtrainorb316e9272014-09-19 23:30:5583 content::Java_NavigationControllerImpl_addToNavigationHistory(
Daniel Bratell7aacf952017-11-21 17:51:2584 env, history,
85 JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
86 index));
dtrainorb316e9272014-09-19 23:30:5587}
88
Scott Violetf4eec902019-04-04 21:20:3489class MapData : public base::SupportsUserData::Data {
90 public:
91 MapData() = default;
Peter Boström828b9022021-09-21 02:28:4392
93 MapData(const MapData&) = delete;
94 MapData& operator=(const MapData&) = delete;
95
Scott Violetf4eec902019-04-04 21:20:3496 ~MapData() override = default;
97
98 static MapData* Get(content::NavigationEntry* entry) {
99 MapData* map_data = static_cast<MapData*>(entry->GetUserData(kMapDataKey));
100 if (map_data)
101 return map_data;
102 auto map_data_ptr = std::make_unique<MapData>();
103 map_data = map_data_ptr.get();
104 entry->SetUserData(kMapDataKey, std::move(map_data_ptr));
105 return map_data;
106 }
107
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58108 base::flat_map<std::string, std::u16string>& map() { return map_; }
Scott Violetf4eec902019-04-04 21:20:34109
110 // base::SupportsUserData::Data:
111 std::unique_ptr<Data> Clone() override {
112 std::unique_ptr<MapData> clone = std::make_unique<MapData>();
113 clone->map_ = map_;
114 return clone;
115 }
116
117 private:
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58118 base::flat_map<std::string, std::u16string> map_;
Scott Violetf4eec902019-04-04 21:20:34119};
120
ajith.v4502cc62014-09-05 17:41:39121} // namespace
[email protected]155c7f22013-12-09 17:07:18122
123namespace content {
124
[email protected]155c7f22013-12-09 17:07:18125NavigationControllerAndroid::NavigationControllerAndroid(
aelias5252baa2016-04-10 01:18:02126 NavigationControllerImpl* navigation_controller)
[email protected]155c7f22013-12-09 17:07:18127 : navigation_controller_(navigation_controller) {
128 JNIEnv* env = AttachCurrentThread();
Aran Gilman37d11632019-10-08 23:07:15129 obj_.Reset(env, Java_NavigationControllerImpl_create(
130 env, reinterpret_cast<intptr_t>(this))
131 .obj());
[email protected]155c7f22013-12-09 17:07:18132}
133
134NavigationControllerAndroid::~NavigationControllerAndroid() {
torne948f3662016-08-16 15:10:44135 Java_NavigationControllerImpl_destroy(AttachCurrentThread(), obj_);
[email protected]155c7f22013-12-09 17:07:18136}
137
138base::android::ScopedJavaLocalRef<jobject>
139NavigationControllerAndroid::GetJavaObject() {
140 return base::android::ScopedJavaLocalRef<jobject>(obj_);
141}
142
tornee1bfee92015-12-01 14:05:01143jboolean NavigationControllerAndroid::CanGoBack(
144 JNIEnv* env,
145 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18146 return navigation_controller_->CanGoBack();
147}
148
tornee1bfee92015-12-01 14:05:01149jboolean NavigationControllerAndroid::CanGoForward(
150 JNIEnv* env,
151 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18152 return navigation_controller_->CanGoForward();
153}
154
tornee1bfee92015-12-01 14:05:01155jboolean NavigationControllerAndroid::CanGoToOffset(
156 JNIEnv* env,
157 const JavaParamRef<jobject>& obj,
158 jint offset) {
WangHui74286d52021-03-31 16:17:15159 return navigation_controller_->CanGoToOffsetWithSkipping(offset);
[email protected]155c7f22013-12-09 17:07:18160}
161
tornee1bfee92015-12-01 14:05:01162void NavigationControllerAndroid::GoBack(JNIEnv* env,
163 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18164 navigation_controller_->GoBack();
165}
166
tornee1bfee92015-12-01 14:05:01167void NavigationControllerAndroid::GoForward(JNIEnv* env,
168 const JavaParamRef<jobject>& obj) {
[email protected]155c7f22013-12-09 17:07:18169 navigation_controller_->GoForward();
170}
171
172void NavigationControllerAndroid::GoToOffset(JNIEnv* env,
tornee1bfee92015-12-01 14:05:01173 const JavaParamRef<jobject>& obj,
[email protected]155c7f22013-12-09 17:07:18174 jint offset) {
WangHui74286d52021-03-31 16:17:15175 navigation_controller_->GoToOffsetWithSkipping(offset);
[email protected]155c7f22013-12-09 17:07:18176}
177
tornee1bfee92015-12-01 14:05:01178jboolean NavigationControllerAndroid::IsInitialNavigation(
179 JNIEnv* env,
180 const JavaParamRef<jobject>& obj) {
dfalcantara0d314d522015-01-05 22:56:43181 return navigation_controller_->IsInitialNavigation();
182}
183
tornee1bfee92015-12-01 14:05:01184void NavigationControllerAndroid::LoadIfNecessary(
185 JNIEnv* env,
186 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29187 navigation_controller_->LoadIfNecessary();
188}
189
tornee1bfee92015-12-01 14:05:01190void NavigationControllerAndroid::ContinuePendingReload(
191 JNIEnv* env,
192 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29193 navigation_controller_->ContinuePendingReload();
194}
195
196void NavigationControllerAndroid::Reload(JNIEnv* env,
tornee1bfee92015-12-01 14:05:01197 const JavaParamRef<jobject>& obj,
[email protected]6d3f32f2014-07-08 08:23:29198 jboolean check_for_repost) {
Rakina Zata Amnid605d462022-06-01 10:17:03199 SCOPED_CRASH_KEY_BOOL("nav_reentrancy_caller2", "Reload_check",
200 (bool)check_for_repost);
toyoshim6142d96f2016-12-19 09:07:25201 navigation_controller_->Reload(ReloadType::NORMAL, check_for_repost);
[email protected]6d3f32f2014-07-08 08:23:29202}
203
toyoshim7dad4b1182016-04-01 14:28:05204void NavigationControllerAndroid::ReloadBypassingCache(
[email protected]6d3f32f2014-07-08 08:23:29205 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01206 const JavaParamRef<jobject>& obj,
[email protected]6d3f32f2014-07-08 08:23:29207 jboolean check_for_repost) {
Rakina Zata Amnid605d462022-06-01 10:17:03208 SCOPED_CRASH_KEY_BOOL("nav_reentrancy_caller2", "ReloadB_check",
209 (bool)check_for_repost);
toyoshim6142d96f2016-12-19 09:07:25210 navigation_controller_->Reload(ReloadType::BYPASSING_CACHE, check_for_repost);
[email protected]6d3f32f2014-07-08 08:23:29211}
212
Matthew Carye7da4b12018-05-02 16:14:16213jboolean NavigationControllerAndroid::NeedsReload(
214 JNIEnv* env,
215 const JavaParamRef<jobject>& obj) {
216 return navigation_controller_->NeedsReload();
217}
218
219void NavigationControllerAndroid::SetNeedsReload(
tornee1bfee92015-12-01 14:05:01220 JNIEnv* env,
221 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29222 navigation_controller_->SetNeedsReload();
223}
224
tornee1bfee92015-12-01 14:05:01225void NavigationControllerAndroid::CancelPendingReload(
226 JNIEnv* env,
227 const JavaParamRef<jobject>& obj) {
[email protected]6d3f32f2014-07-08 08:23:29228 navigation_controller_->CancelPendingReload();
229}
230
tornee1bfee92015-12-01 14:05:01231void NavigationControllerAndroid::GoToNavigationIndex(
232 JNIEnv* env,
233 const JavaParamRef<jobject>& obj,
234 jint index) {
[email protected]155c7f22013-12-09 17:07:18235 navigation_controller_->GoToIndex(index);
236}
237
Pete Williamson1d87f4622022-10-18 19:36:43238base::android::ScopedJavaGlobalRef<jobject>
239NavigationControllerAndroid::LoadUrl(
lizebe8adeb82015-08-20 12:18:10240 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01241 const JavaParamRef<jobject>& obj,
242 const JavaParamRef<jstring>& url,
lizebe8adeb82015-08-20 12:18:10243 jint load_url_type,
244 jint transition_type,
tornee1bfee92015-12-01 14:05:01245 const JavaParamRef<jstring>& j_referrer_url,
lizebe8adeb82015-08-20 12:18:10246 jint referrer_policy,
247 jint ua_override_option,
tornee1bfee92015-12-01 14:05:01248 const JavaParamRef<jstring>& extra_headers,
lukasza477a5a22016-06-16 18:28:43249 const JavaParamRef<jobject>& j_post_data,
tornee1bfee92015-12-01 14:05:01250 const JavaParamRef<jstring>& base_url_for_data_url,
251 const JavaParamRef<jstring>& virtual_url_for_data_url,
mnaganovbf087422015-12-16 05:10:03252 const JavaParamRef<jstring>& data_url_as_string,
lizebe8adeb82015-08-20 12:18:10253 jboolean can_load_local_resources,
254 jboolean is_renderer_initiated,
Michael Thiessend3c9a032021-04-19 17:01:37255 jboolean should_replace_current_entry,
256 const JavaParamRef<jobject>& j_initiator_origin,
257 jboolean has_user_gesture,
258 jboolean should_clear_history_list,
John Delaney43de85fd62023-05-24 17:31:39259 const base::android::JavaParamRef<jobject>& j_impression,
Brandon Wyliea20e67ae2022-07-26 22:01:20260 jlong input_start,
261 jlong navigation_ui_data_ptr) {
ajith.v4502cc62014-09-05 17:41:39262 DCHECK(url);
263 NavigationController::LoadURLParams params(
264 GURL(ConvertJavaStringToUTF8(env, url)));
Brandon Wyliea20e67ae2022-07-26 22:01:20265 // Wrap the raw pointer in case on an early return.
266 std::unique_ptr<NavigationUIData> navigation_ui_data = base::WrapUnique(
267 reinterpret_cast<NavigationUIData*>(navigation_ui_data_ptr));
ajith.v4502cc62014-09-05 17:41:39268 params.load_type =
269 static_cast<NavigationController::LoadURLType>(load_url_type);
Sylvain Defresnec6ccc77d2014-09-19 10:19:35270 params.transition_type = ui::PageTransitionFromInt(transition_type);
ajith.v4502cc62014-09-05 17:41:39271 params.override_user_agent =
272 static_cast<NavigationController::UserAgentOverrideOption>(
273 ua_override_option);
274 params.can_load_local_resources = can_load_local_resources;
275 params.is_renderer_initiated = is_renderer_initiated;
lizebe8adeb82015-08-20 12:18:10276 params.should_replace_current_entry = should_replace_current_entry;
Michael Thiessend3c9a032021-04-19 17:01:37277 params.has_user_gesture = has_user_gesture;
278 params.should_clear_history_list = should_clear_history_list;
ajith.v4502cc62014-09-05 17:41:39279
John Delaney43de85fd62023-05-24 17:31:39280 if (j_impression) {
281 params.initiator_frame_token =
282 GetInitiatorFrameTokenFromJavaImpression(env, j_impression);
283 params.initiator_process_id =
284 GetInitiatorProcessIDFromJavaImpression(env, j_impression);
285 blink::Impression impression;
286 impression.attribution_src_token =
287 GetAttributionSrcTokenFromJavaImpression(env, j_impression).value();
288 impression.nav_type = blink::mojom::AttributionNavigationType::kContextMenu;
289 impression.runtime_features =
290 GetAttributionRuntimeFeaturesFromJavaImpression(env, j_impression);
291 params.impression = impression;
292 }
293
ajith.v4502cc62014-09-05 17:41:39294 if (extra_headers)
295 params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);
296
John Abd-El-Maleka59411632018-01-10 20:08:28297 params.post_data = ExtractResourceRequestBodyFromJavaObject(env, j_post_data);
ajith.v4502cc62014-09-05 17:41:39298
299 if (base_url_for_data_url) {
300 params.base_url_for_data_url =
301 GURL(ConvertJavaStringToUTF8(env, base_url_for_data_url));
302 }
303
304 if (virtual_url_for_data_url) {
305 params.virtual_url_for_data_url =
306 GURL(ConvertJavaStringToUTF8(env, virtual_url_for_data_url));
307 }
308
mnaganovbf087422015-12-16 05:10:03309 if (data_url_as_string) {
Daniel Chengef9f4b72017-10-18 08:56:17310 // Treat |data_url_as_string| as if we were intending to put it into a GURL
311 // field. Note that kMaxURLChars is only enforced when serializing URLs
312 // for IPC.
313 GURL data_url = GURL(ConvertJavaStringToUTF8(env, data_url_as_string));
314 DCHECK(data_url.SchemeIs(url::kDataScheme));
mnaganovbf087422015-12-16 05:10:03315 DCHECK(params.url.SchemeIs(url::kDataScheme));
316#if DCHECK_IS_ON()
317 {
318 std::string mime_type, charset, data;
319 DCHECK(net::DataURL::Parse(params.url, &mime_type, &charset, &data));
320 DCHECK(data.empty());
321 }
Daniel Chengef9f4b72017-10-18 08:56:17322#endif
323 std::string s = data_url.spec();
Jongmok Kimc5491082022-10-19 09:17:59324 params.data_url_as_string =
325 base::MakeRefCounted<base::RefCountedString>(std::move(s));
mnaganovbf087422015-12-16 05:10:03326 }
327
ajith.v4502cc62014-09-05 17:41:39328 if (j_referrer_url) {
Lukasz Anforowicza192eb952019-10-15 19:22:22329 params.referrer =
330 Referrer(GURL(ConvertJavaStringToUTF8(env, j_referrer_url)),
331 Referrer::ConvertToPolicy(referrer_policy));
ajith.v4502cc62014-09-05 17:41:39332 }
333
Michael Thiessend3c9a032021-04-19 17:01:37334 if (j_initiator_origin) {
335 params.initiator_origin = url::Origin::FromJavaObject(j_initiator_origin);
336 }
337
338 if (input_start != 0)
339 params.input_start = base::TimeTicks::FromUptimeMillis(input_start);
340
Brandon Wyliea20e67ae2022-07-26 22:01:20341 params.navigation_ui_data = std::move(navigation_ui_data);
342
Pete Williamson1d87f4622022-10-18 19:36:43343 base::WeakPtr<NavigationHandle> handle =
344 navigation_controller_->LoadURLWithParams(params);
345
346 if (!handle) {
347 return nullptr;
348 }
349
350 return base::android::ScopedJavaGlobalRef<jobject>(
351 handle->GetJavaNavigationHandle());
ajith.v4502cc62014-09-05 17:41:39352}
353
tornee1bfee92015-12-01 14:05:01354void NavigationControllerAndroid::ClearHistory(
355 JNIEnv* env,
356 const JavaParamRef<jobject>& obj) {
ajith.v4502cc62014-09-05 17:41:39357 // TODO(creis): Do callers of this need to know if it fails?
358 if (navigation_controller_->CanPruneAllButLastCommitted())
359 navigation_controller_->PruneAllButLastCommitted();
360}
361
tornee1bfee92015-12-01 14:05:01362jint NavigationControllerAndroid::GetNavigationHistory(
363 JNIEnv* env,
364 const JavaParamRef<jobject>& obj,
365 const JavaParamRef<jobject>& history) {
ajith.v4502cc62014-09-05 17:41:39366 // Iterate through navigation entries to populate the list
367 int count = navigation_controller_->GetEntryCount();
368 for (int i = 0; i < count; ++i) {
Daniel Bratell7aacf952017-11-21 17:51:25369 JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
dtrainorb316e9272014-09-19 23:30:55370 env, history, navigation_controller_->GetEntryAtIndex(i), i);
ajith.v4502cc62014-09-05 17:41:39371 }
372
373 return navigation_controller_->GetCurrentEntryIndex();
374}
375
376void NavigationControllerAndroid::GetDirectedNavigationHistory(
377 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01378 const JavaParamRef<jobject>& obj,
379 const JavaParamRef<jobject>& history,
ajith.v4502cc62014-09-05 17:41:39380 jboolean is_forward,
381 jint max_entries) {
382 // Iterate through navigation entries to populate the list
383 int count = navigation_controller_->GetEntryCount();
384 int num_added = 0;
385 int increment_value = is_forward ? 1 : -1;
386 for (int i = navigation_controller_->GetCurrentEntryIndex() + increment_value;
Aran Gilman37d11632019-10-08 23:07:15387 i >= 0 && i < count; i += increment_value) {
ajith.v4502cc62014-09-05 17:41:39388 if (num_added >= max_entries)
389 break;
390
Daniel Bratell7aacf952017-11-21 17:51:25391 JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
dtrainorb316e9272014-09-19 23:30:55392 env, history, navigation_controller_->GetEntryAtIndex(i), i);
ajith.v4502cc62014-09-05 17:41:39393 num_added++;
394 }
395}
396
tornee1bfee92015-12-01 14:05:01397void NavigationControllerAndroid::ClearSslPreferences(
398 JNIEnv* env,
399 const JavaParamRef<jobject>& obj) {
Lukasz Anforowicza192eb952019-10-15 19:22:22400 SSLHostStateDelegate* delegate =
ajith.v4502cc62014-09-05 17:41:39401 navigation_controller_->GetBrowserContext()->GetSSLHostStateDelegate();
402 if (delegate)
danakj1606c572019-11-27 22:34:03403 delegate->Clear(base::NullCallback());
ajith.v4502cc62014-09-05 17:41:39404}
405
tornee1bfee92015-12-01 14:05:01406bool NavigationControllerAndroid::GetUseDesktopUserAgent(
407 JNIEnv* env,
408 const JavaParamRef<jobject>& obj) {
Mohamed Abdelhalim676259c2019-06-18 07:27:54409 NavigationEntry* entry = navigation_controller_->GetLastCommittedEntry();
ajith.v4502cc62014-09-05 17:41:39410 return entry && entry->GetIsOverridingUserAgent();
411}
412
413void NavigationControllerAndroid::SetUseDesktopUserAgent(
414 JNIEnv* env,
tornee1bfee92015-12-01 14:05:01415 const JavaParamRef<jobject>& obj,
ajith.v4502cc62014-09-05 17:41:39416 jboolean enabled,
Shu Yanga0b22212022-07-08 16:44:52417 jboolean reload_on_state_change,
418 jint source) {
Rakina Zata Amnid605d462022-06-01 10:17:03419 SCOPED_CRASH_KEY_BOOL("nav_reentrancy_caller2", "SetUA_enabled",
420 (bool)enabled);
ajith.v4502cc62014-09-05 17:41:39421 if (GetUseDesktopUserAgent(env, obj) == enabled)
422 return;
423
Rakina Zata Amni148dcad72022-06-08 14:53:50424 if (navigation_controller_->in_navigate_to_pending_entry() &&
425 reload_on_state_change) {
Shu Yanga0b22212022-07-08 16:44:52426 // Sometimes it's possible to call this function in response to a
Rakina Zata Amni148dcad72022-06-08 14:53:50427 // navigation to a pending entry. In this case, we should avoid triggering
428 // another navigation synchronously, as it will crash due to navigation
429 // re-entrancy checks. To do that, post a task to update the UA and
430 // reload asynchronously.
431 // TODO(https://crbug.com/1327907): Figure out the case that leads to this
432 // situation and avoid calling this function entirely in that case. For now,
433 // do a do a DumpWithoutCrashing so that we can investigate.
434 GetUIThreadTaskRunner({})->PostTask(
435 FROM_HERE,
436 base::BindOnce(
437 &NavigationControllerAndroid::SetUseDesktopUserAgentInternal,
438 weak_factory_.GetWeakPtr(), enabled, reload_on_state_change));
Shu Yanga0b22212022-07-08 16:44:52439 LOG(WARNING) << "NavigationControllerAndroid::SetUseDesktopUserAgent "
440 << "triggers re-entrant navigation, override: "
441 << (bool)enabled << ", source: " << (int)source;
442 SCOPED_CRASH_KEY_NUMBER("SetUseDesktopUserAgent", "caller", (int)source);
Rakina Zata Amni148dcad72022-06-08 14:53:50443 base::debug::DumpWithoutCrashing();
444 } else {
445 SetUseDesktopUserAgentInternal(enabled, reload_on_state_change);
446 }
447}
448
449void NavigationControllerAndroid::SetUseDesktopUserAgentInternal(
450 bool enabled,
451 bool reload_on_state_change) {
ajith.v4502cc62014-09-05 17:41:39452 // Make sure the navigation entry actually exists.
Mohamed Abdelhalim676259c2019-06-18 07:27:54453 NavigationEntry* entry = navigation_controller_->GetLastCommittedEntry();
Shu Yang31063532023-02-19 00:53:14454 // TODO(crbug.com/1414625): Early return for initial NavigationEntries as a
455 // workaround. Currently, doing a reload while on the initial NavigationEntry
456 // might result in committing an unrelated pending NavigationEntry and
457 // mistakenly marking that entry as an initial NavigationEntry. That will
458 // cause problems, such as the URL bar showing about:blank instead of the URL
459 // of the NavigationEntry. To prevent that happening in this case, skip
460 // reloading initial NavigationEntries entirely. This is a short-term fix,
461 // while we work on a long-term fix to no longer mistakenly mark the unrelated
462 // pending NavigationEntry as the initial NavigationEntry.
463 if (!entry || entry->IsInitialEntry()) {
ajith.v4502cc62014-09-05 17:41:39464 return;
Shu Yang31063532023-02-19 00:53:14465 }
ajith.v4502cc62014-09-05 17:41:39466
467 // Set the flag in the NavigationEntry.
468 entry->SetIsOverridingUserAgent(enabled);
aelias5252baa2016-04-10 01:18:02469 navigation_controller_->delegate()->UpdateOverridingUserAgent();
ajith.v4502cc62014-09-05 17:41:39470
471 // Send the override to the renderer.
472 if (reload_on_state_change) {
473 // Reloading the page will send the override down as part of the
474 // navigation IPC message.
yoichio4f7be0c2016-12-20 08:27:10475 navigation_controller_->Reload(ReloadType::ORIGINAL_REQUEST_URL, true);
ajith.v4502cc62014-09-05 17:41:39476 }
477}
478
dtrainorb316e9272014-09-19 23:30:55479base::android::ScopedJavaLocalRef<jobject>
dfalcantaraf5d7ff812015-01-16 22:58:03480NavigationControllerAndroid::GetEntryAtIndex(JNIEnv* env,
tornee1bfee92015-12-01 14:05:01481 const JavaParamRef<jobject>& obj,
dfalcantaraf5d7ff812015-01-16 22:58:03482 int index) {
483 if (index < 0 || index >= navigation_controller_->GetEntryCount())
484 return base::android::ScopedJavaLocalRef<jobject>();
485
Lukasz Anforowicza192eb952019-10-15 19:22:22486 NavigationEntry* entry = navigation_controller_->GetEntryAtIndex(index);
Daniel Bratell7aacf952017-11-21 17:51:25487 return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
488 index);
dfalcantaraf5d7ff812015-01-16 22:58:03489}
490
491base::android::ScopedJavaLocalRef<jobject>
Ted Chocaa84a512019-04-23 19:15:40492NavigationControllerAndroid::GetVisibleEntry(JNIEnv* env,
493 const JavaParamRef<jobject>& obj) {
Lukasz Anforowicza192eb952019-10-15 19:22:22494 NavigationEntry* entry = navigation_controller_->GetVisibleEntry();
Ted Chocaa84a512019-04-23 19:15:40495
496 if (!entry)
497 return base::android::ScopedJavaLocalRef<jobject>();
498
499 return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
500 /*index=*/-1);
501}
502
503base::android::ScopedJavaLocalRef<jobject>
tornee1bfee92015-12-01 14:05:01504NavigationControllerAndroid::GetPendingEntry(JNIEnv* env,
505 const JavaParamRef<jobject>& obj) {
Lukasz Anforowicza192eb952019-10-15 19:22:22506 NavigationEntry* entry = navigation_controller_->GetPendingEntry();
dtrainorb316e9272014-09-19 23:30:55507
508 if (!entry)
509 return base::android::ScopedJavaLocalRef<jobject>();
510
Daniel Bratell7aacf952017-11-21 17:51:25511 return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(
dtrainorb316e9272014-09-19 23:30:55512 env, entry, navigation_controller_->GetPendingEntryIndex());
513}
514
tornee1bfee92015-12-01 14:05:01515jint NavigationControllerAndroid::GetLastCommittedEntryIndex(
516 JNIEnv* env,
517 const JavaParamRef<jobject>& obj) {
jaekyun45bc8c52014-11-03 01:00:21518 return navigation_controller_->GetLastCommittedEntryIndex();
519}
520
tornee1bfee92015-12-01 14:05:01521jboolean NavigationControllerAndroid::RemoveEntryAtIndex(
522 JNIEnv* env,
523 const JavaParamRef<jobject>& obj,
524 jint index) {
jaekyun45bc8c52014-11-03 01:00:21525 return navigation_controller_->RemoveEntryAtIndex(index);
526}
527
Michael Thiessen9b14d512019-09-23 21:19:47528void NavigationControllerAndroid::PruneForwardEntries(
529 JNIEnv* env,
530 const JavaParamRef<jobject>& obj) {
531 return navigation_controller_->PruneForwardEntries();
532}
533
mvanouwerkerk5b1519e2016-09-27 15:47:46534ScopedJavaLocalRef<jstring> NavigationControllerAndroid::GetEntryExtraData(
535 JNIEnv* env,
536 const JavaParamRef<jobject>& obj,
537 jint index,
538 const JavaParamRef<jstring>& jkey) {
539 if (index < 0 || index >= navigation_controller_->GetEntryCount())
540 return ScopedJavaLocalRef<jstring>();
541
542 std::string key = base::android::ConvertJavaStringToUTF8(env, jkey);
Scott Violetf4eec902019-04-04 21:20:34543 MapData* map_data =
544 MapData::Get(navigation_controller_->GetEntryAtIndex(index));
545 auto iter = map_data->map().find(key);
546 return ConvertUTF16ToJavaString(
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58547 env, iter == map_data->map().end() ? std::u16string() : iter->second);
mvanouwerkerk5b1519e2016-09-27 15:47:46548}
549
550void NavigationControllerAndroid::SetEntryExtraData(
551 JNIEnv* env,
552 const JavaParamRef<jobject>& obj,
553 jint index,
554 const JavaParamRef<jstring>& jkey,
555 const JavaParamRef<jstring>& jvalue) {
556 if (index < 0 || index >= navigation_controller_->GetEntryCount())
557 return;
558
559 std::string key = base::android::ConvertJavaStringToUTF8(env, jkey);
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58560 std::u16string value = base::android::ConvertJavaStringToUTF16(env, jvalue);
Scott Violetf4eec902019-04-04 21:20:34561 MapData* map_data =
562 MapData::Get(navigation_controller_->GetEntryAtIndex(index));
563 map_data->map()[key] = value;
mvanouwerkerk5b1519e2016-09-27 15:47:46564}
565
Shivani Sharmaa5637cf2019-02-13 17:20:48566jboolean NavigationControllerAndroid::IsEntryMarkedToBeSkipped(
567 JNIEnv* env,
568 const base::android::JavaParamRef<jobject>& obj,
569 jint index) {
570 return navigation_controller_->IsEntryMarkedToBeSkipped(index);
571}
572
[email protected]155c7f22013-12-09 17:07:18573} // namespace content