1 // Copyright 2012 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 "android_webview/browser/aw_contents.h"
6
7 #include <limits>
8 #include <memory>
9 #include <utility>
10
11 #include "android_webview/browser/aw_autofill_client.h"
12 #include "android_webview/browser/aw_browser_context.h"
13 #include "android_webview/browser/aw_browser_main_parts.h"
14 #include "android_webview/browser/aw_contents_client_bridge.h"
15 #include "android_webview/browser/aw_contents_io_thread_client.h"
16 #include "android_webview/browser/aw_pdf_exporter.h"
17 #include "android_webview/browser/aw_render_process.h"
18 #include "android_webview/browser/aw_renderer_priority.h"
19 #include "android_webview/browser/aw_resource_context.h"
20 #include "android_webview/browser/aw_settings.h"
21 #include "android_webview/browser/aw_web_contents_delegate.h"
22 #include "android_webview/browser/gfx/aw_gl_functor.h"
23 #include "android_webview/browser/gfx/aw_picture.h"
24 #include "android_webview/browser/gfx/browser_view_renderer.h"
25 #include "android_webview/browser/gfx/child_frame.h"
26 #include "android_webview/browser/gfx/gpu_service_web_view.h"
27 #include "android_webview/browser/gfx/java_browser_view_renderer_helper.h"
28 #include "android_webview/browser/gfx/render_thread_manager.h"
29 #include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
30 #include "android_webview/browser/js_java_interaction/aw_web_message_host_factory.h"
31 #include "android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.h"
32 #include "android_webview/browser/page_load_metrics/page_load_metrics_initialize.h"
33 #include "android_webview/browser/permission/aw_permission_request.h"
34 #include "android_webview/browser/permission/permission_request_handler.h"
35 #include "android_webview/browser/permission/simple_permission_request.h"
36 #include "android_webview/browser/state_serializer.h"
37 #include "android_webview/browser_jni_headers/AwContents_jni.h"
38 #include "android_webview/common/aw_hit_test_data.h"
39 #include "android_webview/common/aw_switches.h"
40 #include "android_webview/common/devtools_instrumentation.h"
41 #include "base/android/jni_android.h"
42 #include "base/android/jni_array.h"
43 #include "base/android/jni_string.h"
44 #include "base/android/locale_utils.h"
45 #include "base/android/scoped_java_ref.h"
46 #include "base/atomicops.h"
47 #include "base/bind.h"
48 #include "base/callback.h"
49 #include "base/callback_helpers.h"
50 #include "base/command_line.h"
51 #include "base/feature_list.h"
52 #include "base/i18n/rtl.h"
53 #include "base/json/json_writer.h"
54 #include "base/location.h"
55 #include "base/macros.h"
56 #include "base/memory/memory_pressure_listener.h"
57 #include "base/no_destructor.h"
58 #include "base/pickle.h"
59 #include "base/single_thread_task_runner.h"
60 #include "base/strings/string16.h"
61 #include "base/supports_user_data.h"
62 #include "base/threading/thread_restrictions.h"
63 #include "base/threading/thread_task_runner_handle.h"
64 #include "components/autofill/android/provider/autofill_provider_android.h"
65 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
66 #include "components/autofill/core/browser/autofill_manager.h"
67 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
68 #include "components/navigation_interception/intercept_navigation_delegate.h"
69 #include "components/safe_browsing/core/features.h"
70 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
71 #include "components/viz/common/surfaces/frame_sink_id.h"
72 #include "content/public/browser/android/child_process_importance.h"
73 #include "content/public/browser/android/synchronous_compositor.h"
74 #include "content/public/browser/browser_task_traits.h"
75 #include "content/public/browser/browser_thread.h"
76 #include "content/public/browser/browsing_data_remover.h"
77 #include "content/public/browser/child_process_security_policy.h"
78 #include "content/public/browser/favicon_status.h"
79 #include "content/public/browser/navigation_entry.h"
80 #include "content/public/browser/navigation_handle.h"
81 #include "content/public/browser/render_frame_host.h"
82 #include "content/public/browser/render_process_host.h"
83 #include "content/public/browser/render_view_host.h"
84 #include "content/public/browser/render_widget_host.h"
85 #include "content/public/browser/render_widget_host_iterator.h"
86 #include "content/public/browser/ssl_status.h"
87 #include "content/public/browser/web_contents.h"
88 #include "content/public/common/mhtml_generation_params.h"
89 #include "content/public/common/use_zoom_for_dsf_policy.h"
90 #include "net/base/auth.h"
91 #include "net/cert/x509_certificate.h"
92 #include "net/cert/x509_util.h"
93 #include "third_party/skia/include/core/SkPicture.h"
94 #include "ui/gfx/android/java_bitmap.h"
95 #include "ui/gfx/geometry/rect_f.h"
96 #include "ui/gfx/geometry/size.h"
97 #include "ui/gfx/image/image.h"
98 struct AwDrawSWFunctionTable;
99
100 using autofill::AutofillManager;
101 using autofill::ContentAutofillDriverFactory;
102 using base::android::AttachCurrentThread;
103 using base::android::ConvertJavaStringToUTF16;
104 using base::android::ConvertJavaStringToUTF8;
105 using base::android::ConvertUTF16ToJavaString;
106 using base::android::ConvertUTF8ToJavaString;
107 using base::android::HasException;
108 using base::android::JavaParamRef;
109 using base::android::JavaRef;
110 using base::android::ScopedJavaGlobalRef;
111 using base::android::ScopedJavaLocalRef;
112 using content::BrowserThread;
113 using content::RenderFrameHost;
114 using content::WebContents;
115 using js_injection::JsCommunicationHost;
116 using navigation_interception::InterceptNavigationDelegate;
117
118 namespace android_webview {
119
120 class CompositorFrameConsumer;
121
122 namespace {
123
124 bool g_should_download_favicons = false;
125
g_locale()126 std::string* g_locale() {
127 static base::NoDestructor<std::string> locale;
128 return locale.get();
129 }
130
g_locale_list()131 std::string* g_locale_list() {
132 static base::NoDestructor<std::string> locale_list;
133 return locale_list.get();
134 }
135
136 const void* const kAwContentsUserDataKey = &kAwContentsUserDataKey;
137 const void* const kComputedRendererPriorityUserDataKey =
138 &kComputedRendererPriorityUserDataKey;
139
140 class AwContentsUserData : public base::SupportsUserData::Data {
141 public:
AwContentsUserData(AwContents * ptr)142 explicit AwContentsUserData(AwContents* ptr) : contents_(ptr) {}
143
GetContents(WebContents * web_contents)144 static AwContents* GetContents(WebContents* web_contents) {
145 if (!web_contents)
146 return NULL;
147 AwContentsUserData* data = static_cast<AwContentsUserData*>(
148 web_contents->GetUserData(kAwContentsUserDataKey));
149 return data ? data->contents_ : NULL;
150 }
151
152 private:
153 AwContents* contents_;
154 };
155
156 base::subtle::Atomic32 g_instance_count = 0;
157
158 } // namespace
159
160 class ScopedAllowInitGLBindings {
161 public:
ScopedAllowInitGLBindings()162 ScopedAllowInitGLBindings() {}
163
~ScopedAllowInitGLBindings()164 ~ScopedAllowInitGLBindings() {}
165
166 private:
167 base::ScopedAllowBlocking allow_blocking_;
168 };
169
170 // static
FromWebContents(WebContents * web_contents)171 AwContents* AwContents::FromWebContents(WebContents* web_contents) {
172 DCHECK_CURRENTLY_ON(BrowserThread::UI);
173 return AwContentsUserData::GetContents(web_contents);
174 }
175
176 // static
JNI_AwContents_UpdateDefaultLocale(JNIEnv * env,const JavaParamRef<jstring> & locale,const JavaParamRef<jstring> & locale_list)177 void JNI_AwContents_UpdateDefaultLocale(
178 JNIEnv* env,
179 const JavaParamRef<jstring>& locale,
180 const JavaParamRef<jstring>& locale_list) {
181 *g_locale() = ConvertJavaStringToUTF8(env, locale);
182 *g_locale_list() = ConvertJavaStringToUTF8(env, locale_list);
183 }
184
185 // static
GetLocale()186 std::string AwContents::GetLocale() {
187 return *g_locale();
188 }
189
190 // static
GetLocaleList()191 std::string AwContents::GetLocaleList() {
192 return *g_locale_list();
193 }
194
195 // static
FromID(int render_process_id,int render_frame_id)196 AwBrowserPermissionRequestDelegate* AwBrowserPermissionRequestDelegate::FromID(
197 int render_process_id,
198 int render_frame_id) {
199 AwContents* aw_contents =
200 AwContents::FromWebContents(content::WebContents::FromRenderFrameHost(
201 content::RenderFrameHost::FromID(render_process_id,
202 render_frame_id)));
203 return aw_contents;
204 }
205
206 // static
207 AwSafeBrowsingUIManager::UIManagerClient*
FromWebContents(WebContents * web_contents)208 AwSafeBrowsingUIManager::UIManagerClient::FromWebContents(
209 WebContents* web_contents) {
210 return AwContents::FromWebContents(web_contents);
211 }
212
213 // static
FromWebContents(content::WebContents * web_contents)214 AwRenderProcessGoneDelegate* AwRenderProcessGoneDelegate::FromWebContents(
215 content::WebContents* web_contents) {
216 return AwContents::FromWebContents(web_contents);
217 }
218
AwContents(std::unique_ptr<WebContents> web_contents)219 AwContents::AwContents(std::unique_ptr<WebContents> web_contents)
220 : content::WebContentsObserver(web_contents.get()),
221 browser_view_renderer_(this, content::GetUIThreadTaskRunner({})),
222 web_contents_(std::move(web_contents)) {
223 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
224 icon_helper_.reset(new IconHelper(web_contents_.get()));
225 icon_helper_->SetListener(this);
226 web_contents_->SetUserData(android_webview::kAwContentsUserDataKey,
227 std::make_unique<AwContentsUserData>(this));
228 browser_view_renderer_.RegisterWithWebContents(web_contents_.get());
229
230 viz::FrameSinkId frame_sink_id;
231 if (web_contents_->GetRenderViewHost()) {
232 frame_sink_id =
233 web_contents_->GetRenderViewHost()->GetWidget()->GetFrameSinkId();
234 }
235
236 browser_view_renderer_.SetActiveFrameSinkId(frame_sink_id);
237 render_view_host_ext_.reset(
238 new AwRenderViewHostExt(this, web_contents_.get()));
239
240 InitializePageLoadMetricsForWebContents(web_contents_.get());
241
242 permission_request_handler_.reset(
243 new PermissionRequestHandler(this, web_contents_.get()));
244
245 AwAutofillClient* autofill_manager_delegate =
246 AwAutofillClient::FromWebContents(web_contents_.get());
247 if (autofill_manager_delegate)
248 InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
249 content::SynchronousCompositor::SetClientForWebContents(
250 web_contents_.get(), &browser_view_renderer_);
251 AwContentsLifecycleNotifier::GetInstance().OnWebViewCreated(this);
252 AwBrowserProcess::GetInstance()->visibility_metrics_logger()->AddClient(this);
253 }
254
SetJavaPeers(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & aw_contents,const JavaParamRef<jobject> & web_contents_delegate,const JavaParamRef<jobject> & contents_client_bridge,const JavaParamRef<jobject> & io_thread_client,const JavaParamRef<jobject> & intercept_navigation_delegate,const JavaParamRef<jobject> & autofill_provider)255 void AwContents::SetJavaPeers(
256 JNIEnv* env,
257 const JavaParamRef<jobject>& obj,
258 const JavaParamRef<jobject>& aw_contents,
259 const JavaParamRef<jobject>& web_contents_delegate,
260 const JavaParamRef<jobject>& contents_client_bridge,
261 const JavaParamRef<jobject>& io_thread_client,
262 const JavaParamRef<jobject>& intercept_navigation_delegate,
263 const JavaParamRef<jobject>& autofill_provider) {
264 DCHECK_CURRENTLY_ON(BrowserThread::UI);
265 // The |aw_content| param is technically spurious as it duplicates |obj| but
266 // is passed over anyway to make the binding more explicit.
267 java_ref_ = JavaObjectWeakGlobalRef(env, aw_contents);
268
269 web_contents_delegate_.reset(
270 new AwWebContentsDelegate(env, web_contents_delegate));
271 web_contents_->SetDelegate(web_contents_delegate_.get());
272
273 contents_client_bridge_.reset(
274 new AwContentsClientBridge(env, contents_client_bridge));
275 AwContentsClientBridge::Associate(web_contents_.get(),
276 contents_client_bridge_.get());
277
278 AwContentsIoThreadClient::Associate(web_contents_.get(), io_thread_client);
279
280 InterceptNavigationDelegate::Associate(
281 web_contents_.get(), std::make_unique<InterceptNavigationDelegate>(
282 env, intercept_navigation_delegate));
283
284 if (autofill_provider) {
285 autofill_provider_ = std::make_unique<autofill::AutofillProviderAndroid>(
286 autofill_provider, web_contents_.get());
287 }
288 }
289
SetSaveFormData(bool enabled)290 void AwContents::SetSaveFormData(bool enabled) {
291 DCHECK_CURRENTLY_ON(BrowserThread::UI);
292 InitAutofillIfNecessary(enabled);
293 // We need to check for the existence, since autofill_manager_delegate
294 // may not be created when the setting is false.
295 if (AwAutofillClient::FromWebContents(web_contents_.get())) {
296 AwAutofillClient::FromWebContents(web_contents_.get())
297 ->SetSaveFormData(enabled);
298 }
299 }
300
InitAutofillIfNecessary(bool autocomplete_enabled)301 void AwContents::InitAutofillIfNecessary(bool autocomplete_enabled) {
302 // Check if the autofill driver factory already exists.
303 content::WebContents* web_contents = web_contents_.get();
304 if (ContentAutofillDriverFactory::FromWebContents(web_contents))
305 return;
306
307 // Check if AutofillProvider is available.
308 DCHECK_CURRENTLY_ON(BrowserThread::UI);
309 JNIEnv* env = AttachCurrentThread();
310 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
311 if (!obj)
312 return;
313
314 // Just return, if the app neither runs on O sdk nor enables autocomplete.
315 if (!autofill_provider_ && !autocomplete_enabled)
316 return;
317
318 AwAutofillClient::CreateForWebContents(web_contents);
319 ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
320 web_contents, AwAutofillClient::FromWebContents(web_contents),
321 base::android::GetDefaultLocaleString(),
322 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER,
323 autofill_provider_.get());
324 }
325
SetAwAutofillClient(const JavaRef<jobject> & client)326 void AwContents::SetAwAutofillClient(const JavaRef<jobject>& client) {
327 DCHECK_CURRENTLY_ON(BrowserThread::UI);
328 JNIEnv* env = AttachCurrentThread();
329 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
330 if (!obj)
331 return;
332 Java_AwContents_setAwAutofillClient(env, obj, client);
333 }
334
~AwContents()335 AwContents::~AwContents() {
336 DCHECK_EQ(this, AwContents::FromWebContents(web_contents_.get()));
337 web_contents_->RemoveUserData(kAwContentsUserDataKey);
338 AwContentsClientBridge::Dissociate(web_contents_.get());
339 if (find_helper_.get())
340 find_helper_->SetListener(NULL);
341 if (icon_helper_.get())
342 icon_helper_->SetListener(NULL);
343 base::subtle::Atomic32 instance_count =
344 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1);
345 // When the last WebView is destroyed free all discardable memory allocated by
346 // Chromium, because the app process may continue to run for a long time
347 // without ever using another WebView.
348 if (instance_count == 0) {
349 // TODO(timvolodine): consider moving NotifyMemoryPressure to
350 // AwContentsLifecycleNotifier (crbug.com/522988).
351 base::MemoryPressureListener::NotifyMemoryPressure(
352 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
353 }
354 browser_view_renderer_.SetCurrentCompositorFrameConsumer(nullptr);
355 AwContentsLifecycleNotifier::GetInstance().OnWebViewDestroyed(this);
356 WebContentsObserver::Observe(nullptr);
357 AwBrowserProcess::GetInstance()->visibility_metrics_logger()->RemoveClient(
358 this);
359 }
360
GetWebContents(JNIEnv * env,const JavaParamRef<jobject> & obj)361 base::android::ScopedJavaLocalRef<jobject> AwContents::GetWebContents(
362 JNIEnv* env,
363 const JavaParamRef<jobject>& obj) {
364 DCHECK_CURRENTLY_ON(BrowserThread::UI);
365 DCHECK(web_contents_);
366 if (!web_contents_)
367 return base::android::ScopedJavaLocalRef<jobject>();
368
369 return web_contents_->GetJavaWebContents();
370 }
371
GetBrowserContext(JNIEnv * env,const JavaParamRef<jobject> & obj)372 base::android::ScopedJavaLocalRef<jobject> AwContents::GetBrowserContext(
373 JNIEnv* env,
374 const JavaParamRef<jobject>& obj) {
375 if (!web_contents_)
376 return base::android::ScopedJavaLocalRef<jobject>();
377 return AwBrowserContext::FromWebContents(web_contents_.get())
378 ->GetJavaBrowserContext();
379 }
380
SetCompositorFrameConsumer(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,jlong compositor_frame_consumer)381 void AwContents::SetCompositorFrameConsumer(
382 JNIEnv* env,
383 const base::android::JavaParamRef<jobject>& obj,
384 jlong compositor_frame_consumer) {
385 browser_view_renderer_.SetCurrentCompositorFrameConsumer(
386 reinterpret_cast<CompositorFrameConsumer*>(compositor_frame_consumer));
387 }
388
GetRenderProcess(JNIEnv * env,const JavaParamRef<jobject> & obj)389 ScopedJavaLocalRef<jobject> AwContents::GetRenderProcess(
390 JNIEnv* env,
391 const JavaParamRef<jobject>& obj) {
392 DCHECK_CURRENTLY_ON(BrowserThread::UI);
393 content::RenderProcessHost* host =
394 web_contents_->GetMainFrame()->GetProcess();
395 if (host->run_renderer_in_process()) {
396 return ScopedJavaLocalRef<jobject>();
397 }
398 AwRenderProcess* render_process =
399 AwRenderProcess::GetInstanceForRenderProcessHost(host);
400 return render_process->GetJavaObject();
401 }
402
Destroy(JNIEnv * env)403 void AwContents::Destroy(JNIEnv* env) {
404 java_ref_.reset();
405 delete this;
406 }
407
JNI_AwContents_Init(JNIEnv * env,jlong browser_context_pointer)408 static jlong JNI_AwContents_Init(JNIEnv* env, jlong browser_context_pointer) {
409 AwBrowserContext* browser_context =
410 reinterpret_cast<AwBrowserContext*>(browser_context_pointer);
411 std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
412 content::WebContents::CreateParams(browser_context)));
413 // Return an 'uninitialized' instance; most work is deferred until the
414 // subsequent SetJavaPeers() call.
415 return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
416 }
417
JNI_AwContents_HasRequiredHardwareExtensions(JNIEnv * env)418 static jboolean JNI_AwContents_HasRequiredHardwareExtensions(JNIEnv* env) {
419 ScopedAllowInitGLBindings scoped_allow_init_gl_bindings;
420 // Make sure GPUInfo is collected. This will initialize GL bindings,
421 // collect GPUInfo, and compute GpuFeatureInfo if they have not been
422 // already done.
423 return GpuServiceWebView::GetInstance()
424 ->gpu_info()
425 .can_support_threaded_texture_mailbox;
426 }
427
JNI_AwContents_SetAwDrawSWFunctionTable(JNIEnv * env,jlong function_table)428 static void JNI_AwContents_SetAwDrawSWFunctionTable(JNIEnv* env,
429 jlong function_table) {
430 RasterHelperSetAwDrawSWFunctionTable(
431 reinterpret_cast<AwDrawSWFunctionTable*>(function_table));
432 }
433
JNI_AwContents_SetAwDrawGLFunctionTable(JNIEnv * env,jlong function_table)434 static void JNI_AwContents_SetAwDrawGLFunctionTable(JNIEnv* env,
435 jlong function_table) {}
436
JNI_AwContents_UpdateOpenWebScreenArea(JNIEnv * env,jint pixels,jint percentage)437 static void JNI_AwContents_UpdateOpenWebScreenArea(JNIEnv* env,
438 jint pixels,
439 jint percentage) {
440 AwBrowserProcess::GetInstance()
441 ->visibility_metrics_logger()
442 ->UpdateOpenWebScreenArea(pixels, percentage);
443 }
444
445 // static
JNI_AwContents_GetNativeInstanceCount(JNIEnv * env)446 jint JNI_AwContents_GetNativeInstanceCount(JNIEnv* env) {
447 return base::subtle::NoBarrier_Load(&g_instance_count);
448 }
449
450 // static
JNI_AwContents_GetSafeBrowsingLocaleForTesting(JNIEnv * env)451 ScopedJavaLocalRef<jstring> JNI_AwContents_GetSafeBrowsingLocaleForTesting(
452 JNIEnv* env) {
453 ScopedJavaLocalRef<jstring> locale =
454 ConvertUTF8ToJavaString(env, base::i18n::GetConfiguredLocale());
455 return locale;
456 }
457
458 namespace {
DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject> & message,bool has_images)459 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message,
460 bool has_images) {
461 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), has_images,
462 message);
463 }
464 } // namespace
465
DocumentHasImages(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & message)466 void AwContents::DocumentHasImages(JNIEnv* env,
467 const JavaParamRef<jobject>& obj,
468 const JavaParamRef<jobject>& message) {
469 DCHECK_CURRENTLY_ON(BrowserThread::UI);
470 ScopedJavaGlobalRef<jobject> j_message;
471 j_message.Reset(env, message);
472 render_view_host_ext_->DocumentHasImages(
473 base::BindOnce(&DocumentHasImagesCallback, j_message));
474 }
475
476 namespace {
GenerateMHTMLCallback(const JavaRef<jobject> & callback,const base::FilePath & path,int64_t size)477 void GenerateMHTMLCallback(const JavaRef<jobject>& callback,
478 const base::FilePath& path,
479 int64_t size) {
480 JNIEnv* env = AttachCurrentThread();
481 // Android files are UTF8, so the path conversion below is safe.
482 Java_AwContents_generateMHTMLCallback(
483 env, ConvertUTF8ToJavaString(env, path.AsUTF8Unsafe()), size, callback);
484 }
485 } // namespace
486
GenerateMHTML(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jstring> & jpath,const JavaParamRef<jobject> & callback)487 void AwContents::GenerateMHTML(JNIEnv* env,
488 const JavaParamRef<jobject>& obj,
489 const JavaParamRef<jstring>& jpath,
490 const JavaParamRef<jobject>& callback) {
491 DCHECK_CURRENTLY_ON(BrowserThread::UI);
492 base::FilePath target_path(ConvertJavaStringToUTF8(env, jpath));
493 web_contents_->GenerateMHTML(
494 content::MHTMLGenerationParams(target_path),
495 base::BindOnce(&GenerateMHTMLCallback,
496 ScopedJavaGlobalRef<jobject>(env, callback), target_path));
497 }
498
CreatePdfExporter(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & pdfExporter)499 void AwContents::CreatePdfExporter(JNIEnv* env,
500 const JavaParamRef<jobject>& obj,
501 const JavaParamRef<jobject>& pdfExporter) {
502 pdf_exporter_.reset(new AwPdfExporter(env, pdfExporter, web_contents_.get()));
503 }
504
OnReceivedHttpAuthRequest(const JavaRef<jobject> & handler,const std::string & host,const std::string & realm)505 bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler,
506 const std::string& host,
507 const std::string& realm) {
508 DCHECK_CURRENTLY_ON(BrowserThread::UI);
509 JNIEnv* env = AttachCurrentThread();
510 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
511 if (!obj)
512 return false;
513
514 ScopedJavaLocalRef<jstring> jhost = ConvertUTF8ToJavaString(env, host);
515 ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm);
516 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
517 "onReceivedHttpAuthRequest");
518 Java_AwContents_onReceivedHttpAuthRequest(env, obj, handler, jhost, jrealm);
519 return true;
520 }
521
SetOffscreenPreRaster(bool enabled)522 void AwContents::SetOffscreenPreRaster(bool enabled) {
523 DCHECK_CURRENTLY_ON(BrowserThread::UI);
524 browser_view_renderer_.SetOffscreenPreRaster(enabled);
525 }
526
AddVisitedLinks(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobjectArray> & jvisited_links)527 void AwContents::AddVisitedLinks(
528 JNIEnv* env,
529 const JavaParamRef<jobject>& obj,
530 const JavaParamRef<jobjectArray>& jvisited_links) {
531 DCHECK_CURRENTLY_ON(BrowserThread::UI);
532 std::vector<base::string16> visited_link_strings;
533 base::android::AppendJavaStringArrayToStringVector(env, jvisited_links,
534 &visited_link_strings);
535
536 std::vector<GURL> visited_link_gurls;
537 std::vector<base::string16>::const_iterator itr;
538 for (itr = visited_link_strings.begin(); itr != visited_link_strings.end();
539 ++itr) {
540 visited_link_gurls.push_back(GURL(*itr));
541 }
542
543 AwBrowserContext::FromWebContents(web_contents_.get())
544 ->AddVisitedURLs(visited_link_gurls);
545 }
546
547 namespace {
548
ShowGeolocationPromptHelperTask(const JavaObjectWeakGlobalRef & java_ref,const GURL & origin)549 void ShowGeolocationPromptHelperTask(const JavaObjectWeakGlobalRef& java_ref,
550 const GURL& origin) {
551 JNIEnv* env = AttachCurrentThread();
552 ScopedJavaLocalRef<jobject> j_ref = java_ref.get(env);
553 if (j_ref.obj()) {
554 ScopedJavaLocalRef<jstring> j_origin(
555 ConvertUTF8ToJavaString(env, origin.spec()));
556 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
557 "onGeolocationPermissionsShowPrompt");
558 Java_AwContents_onGeolocationPermissionsShowPrompt(env, j_ref, j_origin);
559 }
560 }
561
ShowGeolocationPromptHelper(const JavaObjectWeakGlobalRef & java_ref,const GURL & origin)562 void ShowGeolocationPromptHelper(const JavaObjectWeakGlobalRef& java_ref,
563 const GURL& origin) {
564 JNIEnv* env = AttachCurrentThread();
565 if (java_ref.get(env).obj()) {
566 content::GetUIThreadTaskRunner({})->PostTask(
567 FROM_HERE,
568 base::BindOnce(&ShowGeolocationPromptHelperTask, java_ref, origin));
569 }
570 }
571
572 } // anonymous namespace
573
ShowGeolocationPrompt(const GURL & requesting_frame,base::OnceCallback<void (bool)> callback)574 void AwContents::ShowGeolocationPrompt(
575 const GURL& requesting_frame,
576 base::OnceCallback<void(bool)> callback) {
577 DCHECK_CURRENTLY_ON(BrowserThread::UI);
578
579 GURL origin = requesting_frame.GetOrigin();
580 bool show_prompt = pending_geolocation_prompts_.empty();
581 pending_geolocation_prompts_.emplace_back(origin, std::move(callback));
582 if (show_prompt) {
583 ShowGeolocationPromptHelper(java_ref_, origin);
584 }
585 }
586
587 // Invoked from Java
InvokeGeolocationCallback(JNIEnv * env,const JavaParamRef<jobject> & obj,jboolean value,const JavaParamRef<jstring> & origin)588 void AwContents::InvokeGeolocationCallback(
589 JNIEnv* env,
590 const JavaParamRef<jobject>& obj,
591 jboolean value,
592 const JavaParamRef<jstring>& origin) {
593 DCHECK_CURRENTLY_ON(BrowserThread::UI);
594 if (pending_geolocation_prompts_.empty())
595 return;
596
597 GURL callback_origin(base::android::ConvertJavaStringToUTF16(env, origin));
598 if (callback_origin.GetOrigin() ==
599 pending_geolocation_prompts_.front().first) {
600 std::move(pending_geolocation_prompts_.front().second).Run(value);
601 pending_geolocation_prompts_.pop_front();
602 if (!pending_geolocation_prompts_.empty()) {
603 ShowGeolocationPromptHelper(java_ref_,
604 pending_geolocation_prompts_.front().first);
605 }
606 }
607 }
608
HideGeolocationPrompt(const GURL & origin)609 void AwContents::HideGeolocationPrompt(const GURL& origin) {
610 DCHECK_CURRENTLY_ON(BrowserThread::UI);
611 bool removed_current_outstanding_callback = false;
612 std::list<OriginCallback>::iterator it = pending_geolocation_prompts_.begin();
613 while (it != pending_geolocation_prompts_.end()) {
614 if ((*it).first == origin.GetOrigin()) {
615 if (it == pending_geolocation_prompts_.begin()) {
616 removed_current_outstanding_callback = true;
617 }
618 it = pending_geolocation_prompts_.erase(it);
619 } else {
620 ++it;
621 }
622 }
623
624 if (removed_current_outstanding_callback) {
625 JNIEnv* env = AttachCurrentThread();
626 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
627 if (j_ref.obj()) {
628 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
629 "onGeolocationPermissionsHidePrompt");
630 Java_AwContents_onGeolocationPermissionsHidePrompt(env, j_ref);
631 }
632 if (!pending_geolocation_prompts_.empty()) {
633 ShowGeolocationPromptHelper(java_ref_,
634 pending_geolocation_prompts_.front().first);
635 }
636 }
637 }
638
OnPermissionRequest(base::android::ScopedJavaLocalRef<jobject> j_request,AwPermissionRequest * request)639 void AwContents::OnPermissionRequest(
640 base::android::ScopedJavaLocalRef<jobject> j_request,
641 AwPermissionRequest* request) {
642 DCHECK(j_request);
643 DCHECK(request);
644
645 JNIEnv* env = AttachCurrentThread();
646 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
647 if (!j_ref) {
648 permission_request_handler_->CancelRequest(request->GetOrigin(),
649 request->GetResources());
650 return;
651 }
652
653 Java_AwContents_onPermissionRequest(env, j_ref, j_request);
654 }
655
OnPermissionRequestCanceled(AwPermissionRequest * request)656 void AwContents::OnPermissionRequestCanceled(AwPermissionRequest* request) {
657 JNIEnv* env = AttachCurrentThread();
658 ScopedJavaLocalRef<jobject> j_request = request->GetJavaObject();
659 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
660 if (!j_request || !j_ref)
661 return;
662
663 Java_AwContents_onPermissionRequestCanceled(env, j_ref, j_request);
664 }
665
PreauthorizePermission(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jstring> & origin,jlong resources)666 void AwContents::PreauthorizePermission(JNIEnv* env,
667 const JavaParamRef<jobject>& obj,
668 const JavaParamRef<jstring>& origin,
669 jlong resources) {
670 permission_request_handler_->PreauthorizePermission(
671 GURL(base::android::ConvertJavaStringToUTF8(env, origin)), resources);
672 }
673
RequestProtectedMediaIdentifierPermission(const GURL & origin,base::OnceCallback<void (bool)> callback)674 void AwContents::RequestProtectedMediaIdentifierPermission(
675 const GURL& origin,
676 base::OnceCallback<void(bool)> callback) {
677 permission_request_handler_->SendRequest(
678 std::make_unique<SimplePermissionRequest>(
679 origin, AwPermissionRequest::ProtectedMediaId, std::move(callback)));
680 }
681
CancelProtectedMediaIdentifierPermissionRequests(const GURL & origin)682 void AwContents::CancelProtectedMediaIdentifierPermissionRequests(
683 const GURL& origin) {
684 permission_request_handler_->CancelRequest(
685 origin, AwPermissionRequest::ProtectedMediaId);
686 }
687
RequestGeolocationPermission(const GURL & origin,base::OnceCallback<void (bool)> callback)688 void AwContents::RequestGeolocationPermission(
689 const GURL& origin,
690 base::OnceCallback<void(bool)> callback) {
691 JNIEnv* env = AttachCurrentThread();
692 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
693 if (!obj)
694 return;
695
696 if (Java_AwContents_useLegacyGeolocationPermissionAPI(env, obj)) {
697 ShowGeolocationPrompt(origin, std::move(callback));
698 return;
699 }
700 permission_request_handler_->SendRequest(
701 std::make_unique<SimplePermissionRequest>(
702 origin, AwPermissionRequest::Geolocation, std::move(callback)));
703 }
704
CancelGeolocationPermissionRequests(const GURL & origin)705 void AwContents::CancelGeolocationPermissionRequests(const GURL& origin) {
706 JNIEnv* env = AttachCurrentThread();
707 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
708 if (!obj)
709 return;
710
711 if (Java_AwContents_useLegacyGeolocationPermissionAPI(env, obj)) {
712 HideGeolocationPrompt(origin);
713 return;
714 }
715 permission_request_handler_->CancelRequest(origin,
716 AwPermissionRequest::Geolocation);
717 }
718
RequestMIDISysexPermission(const GURL & origin,base::OnceCallback<void (bool)> callback)719 void AwContents::RequestMIDISysexPermission(
720 const GURL& origin,
721 base::OnceCallback<void(bool)> callback) {
722 permission_request_handler_->SendRequest(
723 std::make_unique<SimplePermissionRequest>(
724 origin, AwPermissionRequest::MIDISysex, std::move(callback)));
725 }
726
CancelMIDISysexPermissionRequests(const GURL & origin)727 void AwContents::CancelMIDISysexPermissionRequests(const GURL& origin) {
728 permission_request_handler_->CancelRequest(
729 origin, AwPermissionRequest::AwPermissionRequest::MIDISysex);
730 }
731
FindAllAsync(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jstring> & search_string)732 void AwContents::FindAllAsync(JNIEnv* env,
733 const JavaParamRef<jobject>& obj,
734 const JavaParamRef<jstring>& search_string) {
735 DCHECK_CURRENTLY_ON(BrowserThread::UI);
736 GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string));
737 }
738
FindNext(JNIEnv * env,const JavaParamRef<jobject> & obj,jboolean forward)739 void AwContents::FindNext(JNIEnv* env,
740 const JavaParamRef<jobject>& obj,
741 jboolean forward) {
742 DCHECK_CURRENTLY_ON(BrowserThread::UI);
743 GetFindHelper()->FindNext(forward);
744 }
745
ClearMatches(JNIEnv * env,const JavaParamRef<jobject> & obj)746 void AwContents::ClearMatches(JNIEnv* env, const JavaParamRef<jobject>& obj) {
747 DCHECK_CURRENTLY_ON(BrowserThread::UI);
748 GetFindHelper()->ClearMatches();
749 }
750
ClearCache(JNIEnv * env,const JavaParamRef<jobject> & obj,jboolean include_disk_files)751 void AwContents::ClearCache(JNIEnv* env,
752 const JavaParamRef<jobject>& obj,
753 jboolean include_disk_files) {
754 DCHECK_CURRENTLY_ON(BrowserThread::UI);
755 AwRenderProcess* aw_render_process =
756 AwRenderProcess::GetInstanceForRenderProcessHost(
757 web_contents_->GetMainFrame()->GetProcess());
758
759 aw_render_process->ClearCache();
760
761 if (include_disk_files) {
762 content::BrowsingDataRemover* remover =
763 content::BrowserContext::GetBrowsingDataRemover(
764 web_contents_->GetBrowserContext());
765 remover->Remove(
766 base::Time(), base::Time::Max(),
767 content::BrowsingDataRemover::DATA_TYPE_CACHE,
768 content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
769 content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);
770 }
771 }
772
GetFindHelper()773 FindHelper* AwContents::GetFindHelper() {
774 DCHECK_CURRENTLY_ON(BrowserThread::UI);
775 if (!find_helper_.get()) {
776 find_helper_.reset(new FindHelper(web_contents_.get()));
777 find_helper_->SetListener(this);
778 }
779 return find_helper_.get();
780 }
781
AllowThirdPartyCookies()782 bool AwContents::AllowThirdPartyCookies() {
783 DCHECK_CURRENTLY_ON(BrowserThread::UI);
784 AwSettings* aw_settings = AwSettings::FromWebContents(web_contents_.get());
785 return aw_settings->GetAllowThirdPartyCookies();
786 }
787
OnFindResultReceived(int active_ordinal,int match_count,bool finished)788 void AwContents::OnFindResultReceived(int active_ordinal,
789 int match_count,
790 bool finished) {
791 DCHECK_CURRENTLY_ON(BrowserThread::UI);
792 JNIEnv* env = AttachCurrentThread();
793 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
794 if (!obj)
795 return;
796
797 Java_AwContents_onFindResultReceived(env, obj, active_ordinal, match_count,
798 finished);
799 }
800
ShouldDownloadFavicon(const GURL & icon_url)801 bool AwContents::ShouldDownloadFavicon(const GURL& icon_url) {
802 return g_should_download_favicons;
803 }
804
OnReceivedIcon(const GURL & icon_url,const SkBitmap & bitmap)805 void AwContents::OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) {
806 DCHECK_CURRENTLY_ON(BrowserThread::UI);
807 JNIEnv* env = AttachCurrentThread();
808 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
809 if (!obj)
810 return;
811
812 content::NavigationEntry* entry =
813 web_contents_->GetController().GetLastCommittedEntry();
814
815 if (entry) {
816 entry->GetFavicon().valid = true;
817 entry->GetFavicon().url = icon_url;
818 entry->GetFavicon().image = gfx::Image::CreateFrom1xBitmap(bitmap);
819 }
820
821 ScopedJavaLocalRef<jobject> java_bitmap =
822 gfx::ConvertToJavaBitmap(bitmap, gfx::OomBehavior::kReturnNullOnOom);
823 if (!java_bitmap) {
824 LOG(WARNING) << "Skipping onReceivedIcon; Not enough memory to convert "
825 "icon to Bitmap.";
826 return;
827 }
828 Java_AwContents_onReceivedIcon(env, obj, java_bitmap);
829 }
830
OnReceivedTouchIconUrl(const std::string & url,bool precomposed)831 void AwContents::OnReceivedTouchIconUrl(const std::string& url,
832 bool precomposed) {
833 DCHECK_CURRENTLY_ON(BrowserThread::UI);
834 JNIEnv* env = AttachCurrentThread();
835 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
836 if (!obj)
837 return;
838
839 Java_AwContents_onReceivedTouchIconUrl(
840 env, obj, ConvertUTF8ToJavaString(env, url), precomposed);
841 }
842
PostInvalidate()843 void AwContents::PostInvalidate() {
844 DCHECK_CURRENTLY_ON(BrowserThread::UI);
845 JNIEnv* env = AttachCurrentThread();
846 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
847 if (obj)
848 Java_AwContents_postInvalidateOnAnimation(env, obj);
849 }
850
OnNewPicture()851 void AwContents::OnNewPicture() {
852 DCHECK_CURRENTLY_ON(BrowserThread::UI);
853 JNIEnv* env = AttachCurrentThread();
854 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
855 if (obj) {
856 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
857 "onNewPicture");
858 Java_AwContents_onNewPicture(env, obj);
859 }
860 }
861
OnViewTreeForceDarkStateChanged(bool view_tree_force_dark_state)862 void AwContents::OnViewTreeForceDarkStateChanged(
863 bool view_tree_force_dark_state) {
864 view_tree_force_dark_state_ = view_tree_force_dark_state;
865 web_contents_->NotifyPreferencesChanged();
866 }
867
GetCertificate(JNIEnv * env,const JavaParamRef<jobject> & obj)868 base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetCertificate(
869 JNIEnv* env,
870 const JavaParamRef<jobject>& obj) {
871 DCHECK_CURRENTLY_ON(BrowserThread::UI);
872 content::NavigationEntry* entry =
873 web_contents_->GetController().GetLastCommittedEntry();
874 if (!entry || !entry->GetSSL().certificate)
875 return ScopedJavaLocalRef<jbyteArray>();
876
877 // Convert the certificate and return it
878 base::StringPiece der_string = net::x509_util::CryptoBufferAsStringPiece(
879 entry->GetSSL().certificate->cert_buffer());
880 return base::android::ToJavaByteArray(
881 env, reinterpret_cast<const uint8_t*>(der_string.data()),
882 der_string.length());
883 }
884
RequestNewHitTestDataAt(JNIEnv * env,const JavaParamRef<jobject> & obj,jfloat x,jfloat y,jfloat touch_major)885 void AwContents::RequestNewHitTestDataAt(JNIEnv* env,
886 const JavaParamRef<jobject>& obj,
887 jfloat x,
888 jfloat y,
889 jfloat touch_major) {
890 DCHECK_CURRENTLY_ON(BrowserThread::UI);
891 gfx::PointF touch_center(x, y);
892 gfx::SizeF touch_area(touch_major, touch_major);
893 render_view_host_ext_->RequestNewHitTestDataAt(touch_center, touch_area);
894 }
895
UpdateLastHitTestData(JNIEnv * env,const JavaParamRef<jobject> & obj)896 void AwContents::UpdateLastHitTestData(JNIEnv* env,
897 const JavaParamRef<jobject>& obj) {
898 DCHECK_CURRENTLY_ON(BrowserThread::UI);
899 if (!render_view_host_ext_->HasNewHitTestData())
900 return;
901
902 const AwHitTestData& data = render_view_host_ext_->GetLastHitTestData();
903 render_view_host_ext_->MarkHitTestDataRead();
904
905 // Make sure to null the Java object if data is empty/invalid.
906 ScopedJavaLocalRef<jstring> extra_data_for_type;
907 if (data.extra_data_for_type.length())
908 extra_data_for_type =
909 ConvertUTF8ToJavaString(env, data.extra_data_for_type);
910
911 ScopedJavaLocalRef<jstring> href;
912 if (data.href.length())
913 href = ConvertUTF16ToJavaString(env, data.href);
914
915 ScopedJavaLocalRef<jstring> anchor_text;
916 if (data.anchor_text.length())
917 anchor_text = ConvertUTF16ToJavaString(env, data.anchor_text);
918
919 ScopedJavaLocalRef<jstring> img_src;
920 if (data.img_src.is_valid())
921 img_src = ConvertUTF8ToJavaString(env, data.img_src.spec());
922
923 Java_AwContents_updateHitTestData(env, obj, data.type, extra_data_for_type,
924 href, anchor_text, img_src);
925 }
926
OnSizeChanged(JNIEnv * env,const JavaParamRef<jobject> & obj,int w,int h,int ow,int oh)927 void AwContents::OnSizeChanged(JNIEnv* env,
928 const JavaParamRef<jobject>& obj,
929 int w,
930 int h,
931 int ow,
932 int oh) {
933 DCHECK_CURRENTLY_ON(BrowserThread::UI);
934 gfx::Size size(w, h);
935 web_contents_->GetNativeView()->OnPhysicalBackingSizeChanged(size);
936 web_contents_->GetNativeView()->OnSizeChanged(w, h);
937 browser_view_renderer_.OnSizeChanged(w, h);
938 AwBrowserProcess::GetInstance()
939 ->visibility_metrics_logger()
940 ->ClientVisibilityChanged(this);
941 }
942
SetViewVisibility(JNIEnv * env,const JavaParamRef<jobject> & obj,bool visible)943 void AwContents::SetViewVisibility(JNIEnv* env,
944 const JavaParamRef<jobject>& obj,
945 bool visible) {
946 DCHECK_CURRENTLY_ON(BrowserThread::UI);
947 browser_view_renderer_.SetViewVisibility(visible);
948 AwBrowserProcess::GetInstance()
949 ->visibility_metrics_logger()
950 ->ClientVisibilityChanged(this);
951 }
952
SetWindowVisibility(JNIEnv * env,const JavaParamRef<jobject> & obj,bool visible)953 void AwContents::SetWindowVisibility(JNIEnv* env,
954 const JavaParamRef<jobject>& obj,
955 bool visible) {
956 DCHECK_CURRENTLY_ON(BrowserThread::UI);
957 browser_view_renderer_.SetWindowVisibility(visible);
958 if (visible)
959 AwContentsLifecycleNotifier::GetInstance().OnWebViewWindowBeVisible(this);
960 else
961 AwContentsLifecycleNotifier::GetInstance().OnWebViewWindowBeInvisible(this);
962 AwBrowserProcess::GetInstance()
963 ->visibility_metrics_logger()
964 ->ClientVisibilityChanged(this);
965 }
966
SetIsPaused(JNIEnv * env,const JavaParamRef<jobject> & obj,bool paused)967 void AwContents::SetIsPaused(JNIEnv* env,
968 const JavaParamRef<jobject>& obj,
969 bool paused) {
970 DCHECK_CURRENTLY_ON(BrowserThread::UI);
971 browser_view_renderer_.SetIsPaused(paused);
972 }
973
OnAttachedToWindow(JNIEnv * env,const JavaParamRef<jobject> & obj,int w,int h)974 void AwContents::OnAttachedToWindow(JNIEnv* env,
975 const JavaParamRef<jobject>& obj,
976 int w,
977 int h) {
978 DCHECK_CURRENTLY_ON(BrowserThread::UI);
979 browser_view_renderer_.OnAttachedToWindow(w, h);
980 AwContentsLifecycleNotifier::GetInstance().OnWebViewAttachedToWindow(this);
981 AwBrowserProcess::GetInstance()
982 ->visibility_metrics_logger()
983 ->ClientVisibilityChanged(this);
984 }
985
OnDetachedFromWindow(JNIEnv * env,const JavaParamRef<jobject> & obj)986 void AwContents::OnDetachedFromWindow(JNIEnv* env,
987 const JavaParamRef<jobject>& obj) {
988 DCHECK_CURRENTLY_ON(BrowserThread::UI);
989 browser_view_renderer_.OnDetachedFromWindow();
990 AwContentsLifecycleNotifier::GetInstance().OnWebViewDetachedFromWindow(this);
991 AwBrowserProcess::GetInstance()
992 ->visibility_metrics_logger()
993 ->ClientVisibilityChanged(this);
994 }
995
IsVisible(JNIEnv * env,const JavaParamRef<jobject> & obj)996 bool AwContents::IsVisible(JNIEnv* env, const JavaParamRef<jobject>& obj) {
997 return browser_view_renderer_.IsClientVisible();
998 }
999
IsDisplayingInterstitialForTesting(JNIEnv * env,const JavaParamRef<jobject> & obj)1000 bool AwContents::IsDisplayingInterstitialForTesting(
1001 JNIEnv* env,
1002 const JavaParamRef<jobject>& obj) {
1003 security_interstitials::SecurityInterstitialTabHelper*
1004 security_interstitial_tab_helper = security_interstitials::
1005 SecurityInterstitialTabHelper::FromWebContents(web_contents_.get());
1006 return security_interstitial_tab_helper &&
1007 security_interstitial_tab_helper->IsDisplayingInterstitial();
1008 }
1009
GetOpaqueState(JNIEnv * env,const JavaParamRef<jobject> & obj)1010 base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetOpaqueState(
1011 JNIEnv* env,
1012 const JavaParamRef<jobject>& obj) {
1013 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1014 // Required optimization in WebViewClassic to not save any state if
1015 // there has been no navigations.
1016 if (!web_contents_->GetController().GetEntryCount())
1017 return ScopedJavaLocalRef<jbyteArray>();
1018
1019 base::Pickle pickle;
1020 WriteToPickle(*web_contents_, &pickle);
1021 return base::android::ToJavaByteArray(
1022 env, reinterpret_cast<const uint8_t*>(pickle.data()), pickle.size());
1023 }
1024
RestoreFromOpaqueState(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jbyteArray> & state)1025 jboolean AwContents::RestoreFromOpaqueState(
1026 JNIEnv* env,
1027 const JavaParamRef<jobject>& obj,
1028 const JavaParamRef<jbyteArray>& state) {
1029 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1030 // TODO(boliu): This copy can be optimized out if this is a performance
1031 // problem.
1032 std::vector<uint8_t> state_vector;
1033 base::android::JavaByteArrayToByteVector(env, state, &state_vector);
1034
1035 base::Pickle pickle(reinterpret_cast<const char*>(state_vector.data()),
1036 state_vector.size());
1037 base::PickleIterator iterator(pickle);
1038
1039 return RestoreFromPickle(&iterator, web_contents_.get());
1040 }
1041
OnDraw(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & canvas,jboolean is_hardware_accelerated,jint scroll_x,jint scroll_y,jint visible_left,jint visible_top,jint visible_right,jint visible_bottom,jboolean force_auxiliary_bitmap_rendering)1042 bool AwContents::OnDraw(JNIEnv* env,
1043 const JavaParamRef<jobject>& obj,
1044 const JavaParamRef<jobject>& canvas,
1045 jboolean is_hardware_accelerated,
1046 jint scroll_x,
1047 jint scroll_y,
1048 jint visible_left,
1049 jint visible_top,
1050 jint visible_right,
1051 jint visible_bottom,
1052 jboolean force_auxiliary_bitmap_rendering) {
1053 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1054 gfx::Vector2d scroll(scroll_x, scroll_y);
1055 browser_view_renderer_.PrepareToDraw(
1056 scroll, gfx::Rect(visible_left, visible_top, visible_right - visible_left,
1057 visible_bottom - visible_top));
1058 if (is_hardware_accelerated && browser_view_renderer_.attached_to_window() &&
1059 !force_auxiliary_bitmap_rendering) {
1060 return browser_view_renderer_.OnDrawHardware();
1061 }
1062
1063 gfx::Size view_size = browser_view_renderer_.size();
1064 if (view_size.IsEmpty()) {
1065 TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_EmptySize",
1066 TRACE_EVENT_SCOPE_THREAD);
1067 return false;
1068 }
1069
1070 // TODO(hush): Right now webview size is passed in as the auxiliary bitmap
1071 // size, which might hurt performance (only for software draws with auxiliary
1072 // bitmap). For better performance, get global visible rect, transform it
1073 // from screen space to view space, then intersect with the webview in
1074 // viewspace. Use the resulting rect as the auxiliary bitmap.
1075 std::unique_ptr<SoftwareCanvasHolder> canvas_holder =
1076 SoftwareCanvasHolder::Create(canvas, scroll, view_size,
1077 force_auxiliary_bitmap_rendering);
1078 if (!canvas_holder || !canvas_holder->GetCanvas()) {
1079 TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoSoftwareCanvas",
1080 TRACE_EVENT_SCOPE_THREAD);
1081 return false;
1082 }
1083 return browser_view_renderer_.OnDrawSoftware(canvas_holder->GetCanvas());
1084 }
1085
NeedToDrawBackgroundColor(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj)1086 bool AwContents::NeedToDrawBackgroundColor(
1087 JNIEnv* env,
1088 const base::android::JavaParamRef<jobject>& obj) {
1089 return browser_view_renderer_.NeedToDrawBackgroundColor();
1090 }
1091
SetPendingWebContentsForPopup(std::unique_ptr<content::WebContents> pending)1092 void AwContents::SetPendingWebContentsForPopup(
1093 std::unique_ptr<content::WebContents> pending) {
1094 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1095 if (pending_contents_.get()) {
1096 // TODO(benm): Support holding multiple pop up window requests.
1097 LOG(WARNING) << "Blocking popup window creation as an outstanding "
1098 << "popup window is still pending.";
1099 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
1100 pending.release());
1101 return;
1102 }
1103 pending_contents_.reset(new AwContents(std::move(pending)));
1104 // Set dip_scale for pending contents, which is necessary for the later
1105 // SynchronousCompositor and InputHandler setup.
1106 pending_contents_->SetDipScaleInternal(browser_view_renderer_.dip_scale());
1107 }
1108
FocusFirstNode(JNIEnv * env,const JavaParamRef<jobject> & obj)1109 void AwContents::FocusFirstNode(JNIEnv* env, const JavaParamRef<jobject>& obj) {
1110 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1111 web_contents_->FocusThroughTabTraversal(false);
1112 }
1113
SetBackgroundColor(JNIEnv * env,const JavaParamRef<jobject> & obj,jint color)1114 void AwContents::SetBackgroundColor(JNIEnv* env,
1115 const JavaParamRef<jobject>& obj,
1116 jint color) {
1117 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1118 render_view_host_ext_->SetBackgroundColor(color);
1119 }
1120
ZoomBy(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,jfloat delta)1121 void AwContents::ZoomBy(JNIEnv* env,
1122 const base::android::JavaParamRef<jobject>& obj,
1123 jfloat delta) {
1124 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1125 browser_view_renderer_.ZoomBy(delta);
1126 }
1127
OnComputeScroll(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong animation_time_millis)1128 void AwContents::OnComputeScroll(JNIEnv* env,
1129 const JavaParamRef<jobject>& obj,
1130 jlong animation_time_millis) {
1131 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1132 browser_view_renderer_.OnComputeScroll(
1133 base::TimeTicks() +
1134 base::TimeDelta::FromMilliseconds(animation_time_millis));
1135 }
1136
ReleasePopupAwContents(JNIEnv * env,const JavaParamRef<jobject> & obj)1137 jlong AwContents::ReleasePopupAwContents(JNIEnv* env,
1138 const JavaParamRef<jobject>& obj) {
1139 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1140 return reinterpret_cast<intptr_t>(pending_contents_.release());
1141 }
1142
GetLocationOnScreen()1143 gfx::Point AwContents::GetLocationOnScreen() {
1144 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1145 JNIEnv* env = AttachCurrentThread();
1146 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1147 if (!obj)
1148 return gfx::Point();
1149 std::vector<int> location;
1150 base::android::JavaIntArrayToIntVector(
1151 env, Java_AwContents_getLocationOnScreen(env, obj), &location);
1152 return gfx::Point(location[0], location[1]);
1153 }
1154
ScrollContainerViewTo(const gfx::Vector2d & new_value)1155 void AwContents::ScrollContainerViewTo(const gfx::Vector2d& new_value) {
1156 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1157 JNIEnv* env = AttachCurrentThread();
1158 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1159 if (!obj)
1160 return;
1161 Java_AwContents_scrollContainerViewTo(env, obj, new_value.x(), new_value.y());
1162 }
1163
UpdateScrollState(const gfx::Vector2d & max_scroll_offset,const gfx::SizeF & contents_size_dip,float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)1164 void AwContents::UpdateScrollState(const gfx::Vector2d& max_scroll_offset,
1165 const gfx::SizeF& contents_size_dip,
1166 float page_scale_factor,
1167 float min_page_scale_factor,
1168 float max_page_scale_factor) {
1169 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1170 JNIEnv* env = AttachCurrentThread();
1171 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1172 if (!obj)
1173 return;
1174 Java_AwContents_updateScrollState(
1175 env, obj, max_scroll_offset.x(), max_scroll_offset.y(),
1176 contents_size_dip.width(), contents_size_dip.height(), page_scale_factor,
1177 min_page_scale_factor, max_page_scale_factor);
1178 }
1179
DidOverscroll(const gfx::Vector2d & overscroll_delta,const gfx::Vector2dF & overscroll_velocity)1180 void AwContents::DidOverscroll(const gfx::Vector2d& overscroll_delta,
1181 const gfx::Vector2dF& overscroll_velocity) {
1182 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1183 JNIEnv* env = AttachCurrentThread();
1184 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1185 if (!obj)
1186 return;
1187 Java_AwContents_didOverscroll(env, obj, overscroll_delta.x(),
1188 overscroll_delta.y(), overscroll_velocity.x(),
1189 overscroll_velocity.y());
1190 }
1191
CreateDrawable()1192 ui::TouchHandleDrawable* AwContents::CreateDrawable() {
1193 JNIEnv* env = AttachCurrentThread();
1194 const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1195 if (!obj)
1196 return nullptr;
1197 return reinterpret_cast<ui::TouchHandleDrawable*>(
1198 Java_AwContents_onCreateTouchHandle(env, obj));
1199 }
1200
SetDipScale(JNIEnv * env,const JavaParamRef<jobject> & obj,jfloat dip_scale)1201 void AwContents::SetDipScale(JNIEnv* env,
1202 const JavaParamRef<jobject>& obj,
1203 jfloat dip_scale) {
1204 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1205 SetDipScaleInternal(dip_scale);
1206 }
1207
IsDisplayingOpenWebContent(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj)1208 jboolean AwContents::IsDisplayingOpenWebContent(
1209 JNIEnv* env,
1210 const base::android::JavaParamRef<jobject>& obj) {
1211 return GetVisibilityInfo().IsDisplayingOpenWebContent();
1212 }
1213
OnInputEvent(JNIEnv * env,const JavaParamRef<jobject> & obj)1214 void AwContents::OnInputEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) {
1215 browser_view_renderer_.OnInputEvent();
1216 }
1217
SetDipScaleInternal(float dip_scale)1218 void AwContents::SetDipScaleInternal(float dip_scale) {
1219 browser_view_renderer_.SetDipScale(dip_scale);
1220 }
1221
ScrollTo(JNIEnv * env,const JavaParamRef<jobject> & obj,jint x,jint y)1222 void AwContents::ScrollTo(JNIEnv* env,
1223 const JavaParamRef<jobject>& obj,
1224 jint x,
1225 jint y) {
1226 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1227 browser_view_renderer_.ScrollTo(gfx::Vector2d(x, y));
1228 }
1229
RestoreScrollAfterTransition(JNIEnv * env,const JavaParamRef<jobject> & obj,jint x,jint y)1230 void AwContents::RestoreScrollAfterTransition(JNIEnv* env,
1231 const JavaParamRef<jobject>& obj,
1232 jint x,
1233 jint y) {
1234 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1235 browser_view_renderer_.RestoreScrollAfterTransition(gfx::Vector2d(x, y));
1236 }
1237
SmoothScroll(JNIEnv * env,const JavaParamRef<jobject> & obj,jint target_x,jint target_y,jlong duration_ms)1238 void AwContents::SmoothScroll(JNIEnv* env,
1239 const JavaParamRef<jobject>& obj,
1240 jint target_x,
1241 jint target_y,
1242 jlong duration_ms) {
1243 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1244
1245 float scale = browser_view_renderer_.page_scale_factor();
1246 if (!content::IsUseZoomForDSFEnabled())
1247 scale *= browser_view_renderer_.dip_scale();
1248
1249 DCHECK_GE(duration_ms, 0);
1250 render_view_host_ext_->SmoothScroll(
1251 target_x / scale, target_y / scale,
1252 base::TimeDelta::FromMilliseconds(duration_ms));
1253 }
1254
OnWebLayoutPageScaleFactorChanged(float page_scale_factor)1255 void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) {
1256 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1257 JNIEnv* env = AttachCurrentThread();
1258 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1259 if (!obj)
1260 return;
1261 Java_AwContents_onWebLayoutPageScaleFactorChanged(env, obj,
1262 page_scale_factor);
1263 }
1264
OnWebLayoutContentsSizeChanged(const gfx::Size & contents_size)1265 void AwContents::OnWebLayoutContentsSizeChanged(
1266 const gfx::Size& contents_size) {
1267 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1268 JNIEnv* env = AttachCurrentThread();
1269 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1270 if (!obj)
1271 return;
1272 gfx::Size contents_size_css =
1273 content::IsUseZoomForDSFEnabled()
1274 ? ScaleToRoundedSize(contents_size,
1275 1 / browser_view_renderer_.dip_scale())
1276 : contents_size;
1277 Java_AwContents_onWebLayoutContentsSizeChanged(
1278 env, obj, contents_size_css.width(), contents_size_css.height());
1279 }
1280
CapturePicture(JNIEnv * env,const JavaParamRef<jobject> & obj,int width,int height)1281 jlong AwContents::CapturePicture(JNIEnv* env,
1282 const JavaParamRef<jobject>& obj,
1283 int width,
1284 int height) {
1285 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1286 return reinterpret_cast<intptr_t>(
1287 new AwPicture(browser_view_renderer_.CapturePicture(width, height)));
1288 }
1289
EnableOnNewPicture(JNIEnv * env,const JavaParamRef<jobject> & obj,jboolean enabled)1290 void AwContents::EnableOnNewPicture(JNIEnv* env,
1291 const JavaParamRef<jobject>& obj,
1292 jboolean enabled) {
1293 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1294 browser_view_renderer_.EnableOnNewPicture(enabled);
1295 }
1296
1297 namespace {
InvokeVisualStateCallback(const JavaObjectWeakGlobalRef & java_ref,jlong request_id,const JavaRef<jobject> & callback,bool result)1298 void InvokeVisualStateCallback(const JavaObjectWeakGlobalRef& java_ref,
1299 jlong request_id,
1300 const JavaRef<jobject>& callback,
1301 bool result) {
1302 JNIEnv* env = AttachCurrentThread();
1303 ScopedJavaLocalRef<jobject> obj = java_ref.get(env);
1304 if (!obj)
1305 return;
1306 Java_AwContents_invokeVisualStateCallback(env, obj, callback, request_id);
1307 }
1308 } // namespace
1309
InsertVisualStateCallback(JNIEnv * env,const JavaParamRef<jobject> & obj,jlong request_id,const JavaParamRef<jobject> & callback)1310 void AwContents::InsertVisualStateCallback(
1311 JNIEnv* env,
1312 const JavaParamRef<jobject>& obj,
1313 jlong request_id,
1314 const JavaParamRef<jobject>& callback) {
1315 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1316 web_contents_->GetMainFrame()->InsertVisualStateCallback(
1317 base::BindOnce(&InvokeVisualStateCallback, java_ref_, request_id,
1318 ScopedJavaGlobalRef<jobject>(env, callback)));
1319 }
1320
GetEffectivePriority(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj)1321 jint AwContents::GetEffectivePriority(
1322 JNIEnv* env,
1323 const base::android::JavaParamRef<jobject>& obj) {
1324 switch (
1325 web_contents_->GetMainFrame()->GetProcess()->GetEffectiveImportance()) {
1326 case content::ChildProcessImportance::NORMAL:
1327 return static_cast<jint>(RendererPriority::WAIVED);
1328 case content::ChildProcessImportance::MODERATE:
1329 return static_cast<jint>(RendererPriority::LOW);
1330 case content::ChildProcessImportance::IMPORTANT:
1331 return static_cast<jint>(RendererPriority::HIGH);
1332 }
1333 NOTREACHED();
1334 return 0;
1335 }
1336
GetJsCommunicationHost()1337 JsCommunicationHost* AwContents::GetJsCommunicationHost() {
1338 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1339 if (!js_communication_host_.get()) {
1340 js_communication_host_ =
1341 std::make_unique<JsCommunicationHost>(web_contents_.get());
1342 }
1343 return js_communication_host_.get();
1344 }
1345
AddDocumentStartJavaScript(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,const base::android::JavaParamRef<jstring> & script,const base::android::JavaParamRef<jobjectArray> & allowed_origin_rules)1346 jint AwContents::AddDocumentStartJavaScript(
1347 JNIEnv* env,
1348 const base::android::JavaParamRef<jobject>& obj,
1349 const base::android::JavaParamRef<jstring>& script,
1350 const base::android::JavaParamRef<jobjectArray>& allowed_origin_rules) {
1351 std::vector<std::string> native_allowed_origin_rule_strings;
1352 AppendJavaStringArrayToStringVector(env, allowed_origin_rules,
1353 &native_allowed_origin_rule_strings);
1354 auto result = GetJsCommunicationHost()->AddDocumentStartJavaScript(
1355 base::android::ConvertJavaStringToUTF16(env, script),
1356 native_allowed_origin_rule_strings);
1357 if (result.error_message) {
1358 env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"),
1359 result.error_message->data());
1360 return -1;
1361 }
1362 DCHECK(result.script_id);
1363 return result.script_id.value();
1364 }
1365
RemoveDocumentStartJavaScript(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,jint script_id)1366 void AwContents::RemoveDocumentStartJavaScript(
1367 JNIEnv* env,
1368 const base::android::JavaParamRef<jobject>& obj,
1369 jint script_id) {
1370 GetJsCommunicationHost()->RemoveDocumentStartJavaScript(script_id);
1371 }
1372
AddWebMessageListener(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,const base::android::JavaParamRef<jobject> & listener,const base::android::JavaParamRef<jstring> & js_object_name,const base::android::JavaParamRef<jobjectArray> & allowed_origin_rules)1373 base::android::ScopedJavaLocalRef<jstring> AwContents::AddWebMessageListener(
1374 JNIEnv* env,
1375 const base::android::JavaParamRef<jobject>& obj,
1376 const base::android::JavaParamRef<jobject>& listener,
1377 const base::android::JavaParamRef<jstring>& js_object_name,
1378 const base::android::JavaParamRef<jobjectArray>& allowed_origin_rules) {
1379 base::string16 native_js_object_name =
1380 base::android::ConvertJavaStringToUTF16(env, js_object_name);
1381 std::vector<std::string> native_allowed_origin_rule_strings;
1382 AppendJavaStringArrayToStringVector(env, allowed_origin_rules,
1383 &native_allowed_origin_rule_strings);
1384 const base::string16 error_message =
1385 GetJsCommunicationHost()->AddWebMessageHostFactory(
1386 std::make_unique<AwWebMessageHostFactory>(listener),
1387 native_js_object_name, native_allowed_origin_rule_strings);
1388 if (error_message.empty())
1389 return nullptr;
1390 return base::android::ConvertUTF16ToJavaString(env, error_message);
1391 }
1392
RemoveWebMessageListener(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,const base::android::JavaParamRef<jstring> & js_object_name)1393 void AwContents::RemoveWebMessageListener(
1394 JNIEnv* env,
1395 const base::android::JavaParamRef<jobject>& obj,
1396 const base::android::JavaParamRef<jstring>& js_object_name) {
1397 GetJsCommunicationHost()->RemoveWebMessageHostFactory(
1398 ConvertJavaStringToUTF16(env, js_object_name));
1399 }
1400
GetJsObjectsInfo(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,const base::android::JavaParamRef<jclass> & clazz)1401 base::android::ScopedJavaLocalRef<jobjectArray> AwContents::GetJsObjectsInfo(
1402 JNIEnv* env,
1403 const base::android::JavaParamRef<jobject>& obj,
1404 const base::android::JavaParamRef<jclass>& clazz) {
1405 if (js_communication_host_.get()) {
1406 return AwWebMessageHostFactory::GetWebMessageListenerInfo(
1407 GetJsCommunicationHost(), env, clazz);
1408 }
1409 return nullptr;
1410 }
1411
ClearView(JNIEnv * env,const JavaParamRef<jobject> & obj)1412 void AwContents::ClearView(JNIEnv* env, const JavaParamRef<jobject>& obj) {
1413 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1414 browser_view_renderer_.ClearView();
1415 }
1416
SetExtraHeadersForUrl(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jstring> & url,const JavaParamRef<jstring> & jextra_headers)1417 void AwContents::SetExtraHeadersForUrl(
1418 JNIEnv* env,
1419 const JavaParamRef<jobject>& obj,
1420 const JavaParamRef<jstring>& url,
1421 const JavaParamRef<jstring>& jextra_headers) {
1422 std::string extra_headers;
1423 if (jextra_headers)
1424 extra_headers = ConvertJavaStringToUTF8(env, jextra_headers);
1425 AwResourceContext* resource_context = static_cast<AwResourceContext*>(
1426 AwBrowserContext::FromWebContents(web_contents_.get())
1427 ->GetResourceContext());
1428 resource_context->SetExtraHeaders(GURL(ConvertJavaStringToUTF8(env, url)),
1429 extra_headers);
1430 }
1431
SetJsOnlineProperty(JNIEnv * env,const JavaParamRef<jobject> & obj,jboolean network_up)1432 void AwContents::SetJsOnlineProperty(JNIEnv* env,
1433 const JavaParamRef<jobject>& obj,
1434 jboolean network_up) {
1435 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1436 AwRenderProcess* aw_render_process =
1437 AwRenderProcess::GetInstanceForRenderProcessHost(
1438 web_contents_->GetMainFrame()->GetProcess());
1439
1440 aw_render_process->SetJsOnlineProperty(network_up);
1441 }
1442
TrimMemory(JNIEnv * env,const JavaParamRef<jobject> & obj,jint level,jboolean visible)1443 void AwContents::TrimMemory(JNIEnv* env,
1444 const JavaParamRef<jobject>& obj,
1445 jint level,
1446 jboolean visible) {
1447 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1448 // Constants from Android ComponentCallbacks2.
1449 enum {
1450 TRIM_MEMORY_RUNNING_LOW = 10,
1451 TRIM_MEMORY_UI_HIDDEN = 20,
1452 TRIM_MEMORY_BACKGROUND = 40,
1453 TRIM_MEMORY_MODERATE = 60,
1454 };
1455
1456 // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
1457 // it does not indicate memory pressure, but merely that the app is
1458 // backgrounded.
1459 if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
1460 return;
1461
1462 // Do not release resources on view we expect to get DrawGL soon.
1463 if (level < TRIM_MEMORY_BACKGROUND && visible)
1464 return;
1465
1466 browser_view_renderer_.TrimMemory();
1467 }
1468
GrantFileSchemeAccesstoChildProcess(JNIEnv * env,const JavaParamRef<jobject> & obj)1469 void AwContents::GrantFileSchemeAccesstoChildProcess(
1470 JNIEnv* env,
1471 const JavaParamRef<jobject>& obj) {
1472 content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestScheme(
1473 web_contents_->GetMainFrame()->GetProcess()->GetID(), url::kFileScheme);
1474 }
1475
ResumeLoadingCreatedPopupWebContents(JNIEnv * env,const JavaParamRef<jobject> & obj)1476 void AwContents::ResumeLoadingCreatedPopupWebContents(
1477 JNIEnv* env,
1478 const JavaParamRef<jobject>& obj) {
1479 web_contents_->ResumeLoadingCreatedWebContents();
1480 }
1481
GetAutofillProvider(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj)1482 jlong AwContents::GetAutofillProvider(
1483 JNIEnv* env,
1484 const base::android::JavaParamRef<jobject>& obj) {
1485 return reinterpret_cast<jlong>(autofill_provider_.get());
1486 }
1487
JNI_AwContents_SetShouldDownloadFavicons(JNIEnv * env)1488 void JNI_AwContents_SetShouldDownloadFavicons(JNIEnv* env) {
1489 g_should_download_favicons = true;
1490 }
1491
RenderViewHostChanged(content::RenderViewHost * old_host,content::RenderViewHost * new_host)1492 void AwContents::RenderViewHostChanged(content::RenderViewHost* old_host,
1493 content::RenderViewHost* new_host) {
1494 DCHECK(new_host);
1495
1496 // At this point, the current RVH may or may not contain a compositor. So
1497 // compositor_ may be nullptr, in which case
1498 // BrowserViewRenderer::DidInitializeCompositor() callback is time when the
1499 // new compositor is constructed.
1500 browser_view_renderer_.SetActiveFrameSinkId(
1501 new_host->GetWidget()->GetFrameSinkId());
1502 }
1503
DidFinishNavigation(content::NavigationHandle * navigation_handle)1504 void AwContents::DidFinishNavigation(
1505 content::NavigationHandle* navigation_handle) {
1506 // If this request was blocked in any way, broadcast an error.
1507 net::Error error_code = navigation_handle->GetNetErrorCode();
1508
1509 bool navigation_successful_and_scheme_http_or_https =
1510 ((error_code == net::OK) &&
1511 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS());
1512 if (navigation_successful_and_scheme_http_or_https != scheme_http_or_https_) {
1513 scheme_http_or_https_ = navigation_successful_and_scheme_http_or_https;
1514 AwBrowserProcess::GetInstance()
1515 ->visibility_metrics_logger()
1516 ->ClientVisibilityChanged(this);
1517 }
1518
1519 if (!net::IsRequestBlockedError(error_code) &&
1520 error_code != net::ERR_ABORTED) {
1521 return;
1522 }
1523
1524 // We do not call OnReceivedError for requests that were blocked due to an
1525 // interstitial showing. OnReceivedError is handled directly by the blocking
1526 // page for interstitials.
1527 if (web_contents_) {
1528 // We can't be showing an interstitial if there is no web_contents.
1529 security_interstitials::SecurityInterstitialTabHelper*
1530 security_interstitial_tab_helper = security_interstitials::
1531 SecurityInterstitialTabHelper::FromWebContents(web_contents_.get());
1532 if (security_interstitial_tab_helper &&
1533 (security_interstitial_tab_helper->IsInterstitialPendingForNavigation(
1534 navigation_handle->GetNavigationId()) ||
1535 security_interstitial_tab_helper->IsDisplayingInterstitial())) {
1536 return;
1537 }
1538 }
1539
1540 AwContentsClientBridge* client =
1541 AwContentsClientBridge::FromWebContents(web_contents_.get());
1542 if (!client)
1543 return;
1544
1545 AwWebResourceRequest request(navigation_handle->GetURL().spec(),
1546 navigation_handle->IsPost() ? "POST" : "GET",
1547 navigation_handle->IsInMainFrame(),
1548 navigation_handle->HasUserGesture(),
1549 net::HttpRequestHeaders());
1550 request.is_renderer_initiated = navigation_handle->IsRendererInitiated();
1551 client->OnReceivedError(request, error_code, false, false);
1552 }
1553
CanShowInterstitial()1554 bool AwContents::CanShowInterstitial() {
1555 JNIEnv* env = AttachCurrentThread();
1556 const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1557 if (!obj)
1558 return false;
1559 return Java_AwContents_canShowInterstitial(env, obj);
1560 }
1561
GetErrorUiType()1562 int AwContents::GetErrorUiType() {
1563 JNIEnv* env = AttachCurrentThread();
1564 const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1565 if (!obj)
1566 return false;
1567 return Java_AwContents_getErrorUiType(env, obj);
1568 }
1569
GetVisibilityInfo()1570 VisibilityMetricsLogger::VisibilityInfo AwContents::GetVisibilityInfo() {
1571 return VisibilityMetricsLogger::VisibilityInfo{
1572 browser_view_renderer_.attached_to_window(),
1573 browser_view_renderer_.view_visible(),
1574 browser_view_renderer_.window_visible(), scheme_http_or_https_};
1575 }
1576
RendererUnresponsive(content::RenderProcessHost * render_process_host)1577 void AwContents::RendererUnresponsive(
1578 content::RenderProcessHost* render_process_host) {
1579 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1580 JNIEnv* env = AttachCurrentThread();
1581 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1582 if (!obj)
1583 return;
1584
1585 AwRenderProcess* aw_render_process =
1586 AwRenderProcess::GetInstanceForRenderProcessHost(render_process_host);
1587 Java_AwContents_onRendererUnresponsive(env, obj,
1588 aw_render_process->GetJavaObject());
1589 }
1590
RendererResponsive(content::RenderProcessHost * render_process_host)1591 void AwContents::RendererResponsive(
1592 content::RenderProcessHost* render_process_host) {
1593 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1594 JNIEnv* env = AttachCurrentThread();
1595 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1596 if (!obj)
1597 return;
1598
1599 AwRenderProcess* aw_render_process =
1600 AwRenderProcess::GetInstanceForRenderProcessHost(render_process_host);
1601 Java_AwContents_onRendererResponsive(env, obj,
1602 aw_render_process->GetJavaObject());
1603 }
1604
OnRenderProcessGone(int child_process_id,bool crashed)1605 AwContents::RenderProcessGoneResult AwContents::OnRenderProcessGone(
1606 int child_process_id,
1607 bool crashed) {
1608 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1609 JNIEnv* env = AttachCurrentThread();
1610 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1611 if (!obj)
1612 return RenderProcessGoneResult::kHandled;
1613
1614 bool result =
1615 Java_AwContents_onRenderProcessGone(env, obj, child_process_id, crashed);
1616
1617 if (HasException(env))
1618 return RenderProcessGoneResult::kException;
1619
1620 return result ? RenderProcessGoneResult::kHandled
1621 : RenderProcessGoneResult::kUnhandled;
1622 }
1623
1624 } // namespace android_webview
1625