Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: android_webview/native/aw_contents.cc

Issue 2863233002: [WebView] Move files from native to browser (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/native/aw_contents.h"
6
7 #include <limits>
8 #include <utility>
9
10 #include "android_webview/browser/aw_browser_context.h"
11 #include "android_webview/browser/aw_browser_main_parts.h"
12 #include "android_webview/browser/aw_resource_context.h"
13 #include "android_webview/browser/browser_view_renderer.h"
14 #include "android_webview/browser/child_frame.h"
15 #include "android_webview/browser/deferred_gpu_command_service.h"
16 #include "android_webview/browser/net_disk_cache_remover.h"
17 #include "android_webview/browser/render_thread_manager.h"
18 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele gate.h"
19 #include "android_webview/browser/scoped_app_gl_state_restore.h"
20 #include "android_webview/common/aw_hit_test_data.h"
21 #include "android_webview/common/aw_switches.h"
22 #include "android_webview/common/devtools_instrumentation.h"
23 #include "android_webview/native/aw_autofill_client.h"
24 #include "android_webview/native/aw_contents_client_bridge.h"
25 #include "android_webview/native/aw_contents_io_thread_client_impl.h"
26 #include "android_webview/native/aw_contents_lifecycle_notifier.h"
27 #include "android_webview/native/aw_gl_functor.h"
28 #include "android_webview/native/aw_pdf_exporter.h"
29 #include "android_webview/native/aw_picture.h"
30 #include "android_webview/native/aw_renderer_priority_manager.h"
31 #include "android_webview/native/aw_web_contents_delegate.h"
32 #include "android_webview/native/java_browser_view_renderer_helper.h"
33 #include "android_webview/native/permission/aw_permission_request.h"
34 #include "android_webview/native/permission/permission_request_handler.h"
35 #include "android_webview/native/permission/simple_permission_request.h"
36 #include "android_webview/native/state_serializer.h"
37 #include "android_webview/public/browser/draw_gl.h"
38 #include "base/android/jni_android.h"
39 #include "base/android/jni_array.h"
40 #include "base/android/jni_string.h"
41 #include "base/android/locale_utils.h"
42 #include "base/android/scoped_java_ref.h"
43 #include "base/atomicops.h"
44 #include "base/bind.h"
45 #include "base/callback.h"
46 #include "base/command_line.h"
47 #include "base/location.h"
48 #include "base/memory/memory_pressure_listener.h"
49 #include "base/memory/ptr_util.h"
50 #include "base/pickle.h"
51 #include "base/single_thread_task_runner.h"
52 #include "base/strings/string16.h"
53 #include "base/supports_user_data.h"
54 #include "base/threading/thread_task_runner_handle.h"
55 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
56 #include "components/autofill/core/browser/autofill_manager.h"
57 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
58 #include "components/navigation_interception/intercept_navigation_delegate.h"
59 #include "content/public/browser/android/content_view_core.h"
60 #include "content/public/browser/android/synchronous_compositor.h"
61 #include "content/public/browser/browser_thread.h"
62 #include "content/public/browser/child_process_security_policy.h"
63 #include "content/public/browser/favicon_status.h"
64 #include "content/public/browser/interstitial_page.h"
65 #include "content/public/browser/message_port_provider.h"
66 #include "content/public/browser/navigation_entry.h"
67 #include "content/public/browser/render_frame_host.h"
68 #include "content/public/browser/render_process_host.h"
69 #include "content/public/browser/render_view_host.h"
70 #include "content/public/browser/render_widget_host.h"
71 #include "content/public/browser/render_widget_host_iterator.h"
72 #include "content/public/browser/ssl_status.h"
73 #include "content/public/browser/web_contents.h"
74 #include "content/public/common/mhtml_generation_params.h"
75 #include "content/public/common/renderer_preferences.h"
76 #include "jni/AwContents_jni.h"
77 #include "net/base/auth.h"
78 #include "net/cert/x509_certificate.h"
79 #include "third_party/skia/include/core/SkPicture.h"
80 #include "ui/gfx/android/java_bitmap.h"
81 #include "ui/gfx/geometry/rect_f.h"
82 #include "ui/gfx/geometry/size.h"
83 #include "ui/gfx/image/image.h"
84 struct AwDrawSWFunctionTable;
85
86 using autofill::ContentAutofillDriverFactory;
87 using autofill::AutofillManager;
88 using base::android::AttachCurrentThread;
89 using base::android::ConvertJavaStringToUTF16;
90 using base::android::ConvertJavaStringToUTF8;
91 using base::android::ConvertUTF16ToJavaString;
92 using base::android::ConvertUTF8ToJavaString;
93 using base::android::JavaParamRef;
94 using base::android::JavaRef;
95 using base::android::ScopedJavaGlobalRef;
96 using base::android::ScopedJavaLocalRef;
97 using navigation_interception::InterceptNavigationDelegate;
98 using content::BrowserThread;
99 using content::ContentViewCore;
100 using content::RenderFrameHost;
101 using content::WebContents;
102
103 namespace android_webview {
104
105 namespace {
106
107 bool g_should_download_favicons = false;
108
109 bool g_force_auxiliary_bitmap_rendering = false;
110
111 std::string g_locale;
112
113 std::string g_locale_list;
114
115 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey;
116 const void* kComputedRendererPriorityUserDataKey =
117 &kComputedRendererPriorityUserDataKey;
118
119 class AwContentsUserData : public base::SupportsUserData::Data {
120 public:
121 explicit AwContentsUserData(AwContents* ptr) : contents_(ptr) {}
122
123 static AwContents* GetContents(WebContents* web_contents) {
124 if (!web_contents)
125 return NULL;
126 AwContentsUserData* data = static_cast<AwContentsUserData*>(
127 web_contents->GetUserData(kAwContentsUserDataKey));
128 return data ? data->contents_ : NULL;
129 }
130
131 private:
132 AwContents* contents_;
133 };
134
135 base::subtle::Atomic32 g_instance_count = 0;
136
137 } // namespace
138
139 // static
140 AwContents* AwContents::FromWebContents(WebContents* web_contents) {
141 DCHECK_CURRENTLY_ON(BrowserThread::UI);
142 return AwContentsUserData::GetContents(web_contents);
143 }
144
145 // static
146 AwContents* AwContents::FromID(int render_process_id, int render_view_id) {
147 content::RenderViewHost* rvh =
148 content::RenderViewHost::FromID(render_process_id, render_view_id);
149 if (!rvh) return NULL;
150 content::WebContents* web_contents =
151 content::WebContents::FromRenderViewHost(rvh);
152 if (!web_contents) return NULL;
153 return FromWebContents(web_contents);
154 }
155
156 // static
157 void UpdateDefaultLocale(JNIEnv* env,
158 const JavaParamRef<jclass>&,
159 const JavaParamRef<jstring>& locale,
160 const JavaParamRef<jstring>& locale_list) {
161 g_locale = ConvertJavaStringToUTF8(env, locale);
162 g_locale_list = ConvertJavaStringToUTF8(env, locale_list);
163 }
164
165 // static
166 std::string AwContents::GetLocale() {
167 return g_locale;
168 }
169
170 // static
171 std::string AwContents::GetLocaleList() {
172 return g_locale_list;
173 }
174
175 // static
176 AwBrowserPermissionRequestDelegate* AwBrowserPermissionRequestDelegate::FromID(
177 int render_process_id, int render_frame_id) {
178 AwContents* aw_contents = AwContents::FromWebContents(
179 content::WebContents::FromRenderFrameHost(
180 content::RenderFrameHost::FromID(render_process_id,
181 render_frame_id)));
182 return aw_contents;
183 }
184
185 // static
186 AwSafeBrowsingUIManager::UIManagerClient*
187 AwSafeBrowsingUIManager::UIManagerClient::FromWebContents(
188 WebContents* web_contents) {
189 return AwContents::FromWebContents(web_contents);
190 }
191
192 // static
193 AwRenderProcessGoneDelegate* AwRenderProcessGoneDelegate::FromWebContents(
194 content::WebContents* web_contents) {
195 return AwContents::FromWebContents(web_contents);
196 }
197
198 AwContents::AwContents(std::unique_ptr<WebContents> web_contents)
199 : content::WebContentsObserver(web_contents.get()),
200 functor_(nullptr),
201 browser_view_renderer_(
202 this,
203 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)),
204 web_contents_(std::move(web_contents)),
205 renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()),
206 renderer_requested_priority_(
207 AwRendererPriorityManager::RENDERER_PRIORITY_HIGH),
208 renderer_priority_waived_when_not_visible_(false) {
209 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
210 icon_helper_.reset(new IconHelper(web_contents_.get()));
211 icon_helper_->SetListener(this);
212 web_contents_->SetUserData(android_webview::kAwContentsUserDataKey,
213 base::MakeUnique<AwContentsUserData>(this));
214 browser_view_renderer_.RegisterWithWebContents(web_contents_.get());
215
216 CompositorID compositor_id;
217 if (web_contents_->GetRenderProcessHost() &&
218 web_contents_->GetRenderViewHost()) {
219 compositor_id.process_id = web_contents_->GetRenderProcessHost()->GetID();
220 compositor_id.routing_id =
221 web_contents_->GetRenderViewHost()->GetRoutingID();
222 }
223
224 browser_view_renderer_.SetActiveCompositorID(compositor_id);
225 render_view_host_ext_.reset(
226 new AwRenderViewHostExt(this, web_contents_.get()));
227
228 permission_request_handler_.reset(
229 new PermissionRequestHandler(this, web_contents_.get()));
230
231 AwAutofillClient* autofill_manager_delegate =
232 AwAutofillClient::FromWebContents(web_contents_.get());
233 if (autofill_manager_delegate)
234 InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
235 content::SynchronousCompositor::SetClientForWebContents(
236 web_contents_.get(), &browser_view_renderer_);
237 UpdateRendererPriority();
238 web_contents_->GetRenderProcessHost()->AddObserver(this);
239 AwContentsLifecycleNotifier::OnWebViewCreated();
240 }
241
242 void AwContents::SetJavaPeers(
243 JNIEnv* env,
244 const JavaParamRef<jobject>& obj,
245 const JavaParamRef<jobject>& aw_contents,
246 const JavaParamRef<jobject>& web_contents_delegate,
247 const JavaParamRef<jobject>& contents_client_bridge,
248 const JavaParamRef<jobject>& io_thread_client,
249 const JavaParamRef<jobject>& intercept_navigation_delegate) {
250 DCHECK_CURRENTLY_ON(BrowserThread::UI);
251 // The |aw_content| param is technically spurious as it duplicates |obj| but
252 // is passed over anyway to make the binding more explicit.
253 java_ref_ = JavaObjectWeakGlobalRef(env, aw_contents);
254
255 web_contents_delegate_.reset(
256 new AwWebContentsDelegate(env, web_contents_delegate));
257 web_contents_->SetDelegate(web_contents_delegate_.get());
258
259 contents_client_bridge_.reset(
260 new AwContentsClientBridge(env, contents_client_bridge));
261 AwContentsClientBridgeBase::Associate(web_contents_.get(),
262 contents_client_bridge_.get());
263
264 AwContentsIoThreadClientImpl::Associate(web_contents_.get(),
265 io_thread_client);
266
267 InterceptNavigationDelegate::Associate(
268 web_contents_.get(), base::MakeUnique<InterceptNavigationDelegate>(
269 env, intercept_navigation_delegate));
270
271 // Finally, having setup the associations, release any deferred requests
272 for (content::RenderFrameHost* rfh : web_contents_->GetAllFrames()) {
273 int render_process_id = rfh->GetProcess()->GetID();
274 int render_frame_id = rfh->GetRoutingID();
275 AwResourceDispatcherHostDelegate::OnIoThreadClientReady(render_process_id,
276 render_frame_id);
277 }
278 }
279
280 void AwContents::SetSaveFormData(bool enabled) {
281 DCHECK_CURRENTLY_ON(BrowserThread::UI);
282 InitAutofillIfNecessary(enabled);
283 // We need to check for the existence, since autofill_manager_delegate
284 // may not be created when the setting is false.
285 if (AwAutofillClient::FromWebContents(web_contents_.get())) {
286 AwAutofillClient::FromWebContents(web_contents_.get())->
287 SetSaveFormData(enabled);
288 }
289 }
290
291 void AwContents::InitAutofillIfNecessary(bool enabled) {
292 // Do not initialize if the feature is not enabled.
293 if (!enabled)
294 return;
295 // Check if the autofill driver factory already exists.
296 content::WebContents* web_contents = web_contents_.get();
297 if (ContentAutofillDriverFactory::FromWebContents(web_contents))
298 return;
299
300 AwAutofillClient::CreateForWebContents(web_contents);
301 ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
302 web_contents, AwAutofillClient::FromWebContents(web_contents),
303 base::android::GetDefaultLocaleString(),
304 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
305 }
306
307 void AwContents::SetAwAutofillClient(const JavaRef<jobject>& client) {
308 DCHECK_CURRENTLY_ON(BrowserThread::UI);
309 JNIEnv* env = AttachCurrentThread();
310 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
311 if (obj.is_null())
312 return;
313 Java_AwContents_setAwAutofillClient(env, obj, client);
314 }
315
316 AwContents::~AwContents() {
317 DCHECK_EQ(this, AwContents::FromWebContents(web_contents_.get()));
318 web_contents_->GetRenderProcessHost()->RemoveObserver(this);
319 UpdateRendererPriority(AwRendererPriorityManager::RENDERER_PRIORITY_WAIVED);
320 web_contents_->RemoveUserData(kAwContentsUserDataKey);
321 if (find_helper_.get())
322 find_helper_->SetListener(NULL);
323 if (icon_helper_.get())
324 icon_helper_->SetListener(NULL);
325 base::subtle::Atomic32 instance_count =
326 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1);
327 // When the last WebView is destroyed free all discardable memory allocated by
328 // Chromium, because the app process may continue to run for a long time
329 // without ever using another WebView.
330 if (instance_count == 0) {
331 // TODO(timvolodine): consider moving NotifyMemoryPressure to
332 // AwContentsLifecycleNotifier (crbug.com/522988).
333 base::MemoryPressureListener::NotifyMemoryPressure(
334 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
335 }
336 SetAwGLFunctor(nullptr);
337 AwContentsLifecycleNotifier::OnWebViewDestroyed();
338 }
339
340 base::android::ScopedJavaLocalRef<jobject> AwContents::GetWebContents(
341 JNIEnv* env,
342 const JavaParamRef<jobject>& obj) {
343 DCHECK_CURRENTLY_ON(BrowserThread::UI);
344 DCHECK(web_contents_);
345 if (!web_contents_)
346 return base::android::ScopedJavaLocalRef<jobject>();
347
348 return web_contents_->GetJavaWebContents();
349 }
350
351 void AwContents::SetAwGLFunctor(AwGLFunctor* functor) {
352 if (functor == functor_) {
353 return;
354 }
355 functor_ = functor;
356 if (functor_) {
357 browser_view_renderer_.SetCurrentCompositorFrameConsumer(
358 functor_->GetCompositorFrameConsumer());
359 } else {
360 browser_view_renderer_.SetCurrentCompositorFrameConsumer(nullptr);
361 }
362 }
363
364 void AwContents::SetAwGLFunctor(JNIEnv* env,
365 const base::android::JavaParamRef<jobject>& obj,
366 jlong gl_functor) {
367 SetAwGLFunctor(reinterpret_cast<AwGLFunctor*>(gl_functor));
368 }
369
370 void AwContents::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
371 java_ref_.reset();
372 delete this;
373 }
374
375 static jlong Init(JNIEnv* env,
376 const JavaParamRef<jclass>&,
377 const JavaParamRef<jobject>& browser_context) {
378 // TODO(joth): Use |browser_context| to get the native BrowserContext, rather
379 // than hard-code the default instance lookup here.
380 std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
381 content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
382 // Return an 'uninitialized' instance; most work is deferred until the
383 // subsequent SetJavaPeers() call.
384 return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
385 }
386
387 static void SetForceAuxiliaryBitmapRendering(
388 JNIEnv* env,
389 const JavaParamRef<jclass>&,
390 jboolean force_auxiliary_bitmap_rendering) {
391 g_force_auxiliary_bitmap_rendering = force_auxiliary_bitmap_rendering;
392 }
393
394 static void SetAwDrawSWFunctionTable(JNIEnv* env,
395 const JavaParamRef<jclass>&,
396 jlong function_table) {
397 RasterHelperSetAwDrawSWFunctionTable(
398 reinterpret_cast<AwDrawSWFunctionTable*>(function_table));
399 }
400
401 static void SetAwDrawGLFunctionTable(JNIEnv* env,
402 const JavaParamRef<jclass>&,
403 jlong function_table) {}
404
405 // static
406 jint GetNativeInstanceCount(JNIEnv* env, const JavaParamRef<jclass>&) {
407 return base::subtle::NoBarrier_Load(&g_instance_count);
408 }
409
410 namespace {
411 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message,
412 bool has_images) {
413 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), has_images,
414 message);
415 }
416 } // namespace
417
418 void AwContents::DocumentHasImages(JNIEnv* env,
419 const JavaParamRef<jobject>& obj,
420 const JavaParamRef<jobject>& message) {
421 DCHECK_CURRENTLY_ON(BrowserThread::UI);
422 ScopedJavaGlobalRef<jobject> j_message;
423 j_message.Reset(env, message);
424 render_view_host_ext_->DocumentHasImages(
425 base::Bind(&DocumentHasImagesCallback, j_message));
426 }
427
428 namespace {
429 void GenerateMHTMLCallback(const JavaRef<jobject>& callback,
430 const base::FilePath& path,
431 int64_t size) {
432 JNIEnv* env = AttachCurrentThread();
433 // Android files are UTF8, so the path conversion below is safe.
434 Java_AwContents_generateMHTMLCallback(
435 env, ConvertUTF8ToJavaString(env, path.AsUTF8Unsafe()), size, callback);
436 }
437 } // namespace
438
439 void AwContents::GenerateMHTML(JNIEnv* env,
440 const JavaParamRef<jobject>& obj,
441 const JavaParamRef<jstring>& jpath,
442 const JavaParamRef<jobject>& callback) {
443 DCHECK_CURRENTLY_ON(BrowserThread::UI);
444 base::FilePath target_path(ConvertJavaStringToUTF8(env, jpath));
445 web_contents_->GenerateMHTML(
446 content::MHTMLGenerationParams(target_path),
447 base::Bind(&GenerateMHTMLCallback,
448 ScopedJavaGlobalRef<jobject>(env, callback), target_path));
449 }
450
451 void AwContents::CreatePdfExporter(JNIEnv* env,
452 const JavaParamRef<jobject>& obj,
453 const JavaParamRef<jobject>& pdfExporter) {
454 pdf_exporter_.reset(
455 new AwPdfExporter(env,
456 pdfExporter,
457 web_contents_.get()));
458 }
459
460 bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler,
461 const std::string& host,
462 const std::string& realm) {
463 DCHECK_CURRENTLY_ON(BrowserThread::UI);
464 JNIEnv* env = AttachCurrentThread();
465 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
466 if (obj.is_null())
467 return false;
468
469 ScopedJavaLocalRef<jstring> jhost = ConvertUTF8ToJavaString(env, host);
470 ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm);
471 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
472 "onReceivedHttpAuthRequest");
473 Java_AwContents_onReceivedHttpAuthRequest(env, obj, handler, jhost, jrealm);
474 return true;
475 }
476
477 void AwContents::SetOffscreenPreRaster(bool enabled) {
478 DCHECK_CURRENTLY_ON(BrowserThread::UI);
479 browser_view_renderer_.SetOffscreenPreRaster(enabled);
480 }
481
482 void AwContents::AddVisitedLinks(
483 JNIEnv* env,
484 const JavaParamRef<jobject>& obj,
485 const JavaParamRef<jobjectArray>& jvisited_links) {
486 DCHECK_CURRENTLY_ON(BrowserThread::UI);
487 std::vector<base::string16> visited_link_strings;
488 base::android::AppendJavaStringArrayToStringVector(
489 env, jvisited_links, &visited_link_strings);
490
491 std::vector<GURL> visited_link_gurls;
492 std::vector<base::string16>::const_iterator itr;
493 for (itr = visited_link_strings.begin(); itr != visited_link_strings.end();
494 ++itr) {
495 visited_link_gurls.push_back(GURL(*itr));
496 }
497
498 AwBrowserContext::FromWebContents(web_contents_.get())
499 ->AddVisitedURLs(visited_link_gurls);
500 }
501
502 bool RegisterAwContents(JNIEnv* env) {
503 return RegisterNativesImpl(env);
504 }
505
506 namespace {
507
508 void ShowGeolocationPromptHelperTask(const JavaObjectWeakGlobalRef& java_ref,
509 const GURL& origin) {
510 JNIEnv* env = AttachCurrentThread();
511 ScopedJavaLocalRef<jobject> j_ref = java_ref.get(env);
512 if (j_ref.obj()) {
513 ScopedJavaLocalRef<jstring> j_origin(
514 ConvertUTF8ToJavaString(env, origin.spec()));
515 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
516 "onGeolocationPermissionsShowPrompt");
517 Java_AwContents_onGeolocationPermissionsShowPrompt(env, j_ref, j_origin);
518 }
519 }
520
521 void ShowGeolocationPromptHelper(const JavaObjectWeakGlobalRef& java_ref,
522 const GURL& origin) {
523 JNIEnv* env = AttachCurrentThread();
524 if (java_ref.get(env).obj()) {
525 content::BrowserThread::PostTask(
526 content::BrowserThread::UI,
527 FROM_HERE,
528 base::Bind(&ShowGeolocationPromptHelperTask,
529 java_ref,
530 origin));
531 }
532 }
533
534 } // anonymous namespace
535
536 void AwContents::ShowGeolocationPrompt(const GURL& requesting_frame,
537 base::Callback<void(bool)> callback) {
538 DCHECK_CURRENTLY_ON(BrowserThread::UI);
539
540 GURL origin = requesting_frame.GetOrigin();
541 bool show_prompt = pending_geolocation_prompts_.empty();
542 pending_geolocation_prompts_.push_back(OriginCallback(origin, callback));
543 if (show_prompt) {
544 ShowGeolocationPromptHelper(java_ref_, origin);
545 }
546 }
547
548 // Invoked from Java
549 void AwContents::InvokeGeolocationCallback(
550 JNIEnv* env,
551 const JavaParamRef<jobject>& obj,
552 jboolean value,
553 const JavaParamRef<jstring>& origin) {
554 DCHECK_CURRENTLY_ON(BrowserThread::UI);
555 if (pending_geolocation_prompts_.empty())
556 return;
557
558 GURL callback_origin(base::android::ConvertJavaStringToUTF16(env, origin));
559 if (callback_origin.GetOrigin() ==
560 pending_geolocation_prompts_.front().first) {
561 pending_geolocation_prompts_.front().second.Run(value);
562 pending_geolocation_prompts_.pop_front();
563 if (!pending_geolocation_prompts_.empty()) {
564 ShowGeolocationPromptHelper(java_ref_,
565 pending_geolocation_prompts_.front().first);
566 }
567 }
568 }
569
570 void AwContents::HideGeolocationPrompt(const GURL& origin) {
571 DCHECK_CURRENTLY_ON(BrowserThread::UI);
572 bool removed_current_outstanding_callback = false;
573 std::list<OriginCallback>::iterator it = pending_geolocation_prompts_.begin();
574 while (it != pending_geolocation_prompts_.end()) {
575 if ((*it).first == origin.GetOrigin()) {
576 if (it == pending_geolocation_prompts_.begin()) {
577 removed_current_outstanding_callback = true;
578 }
579 it = pending_geolocation_prompts_.erase(it);
580 } else {
581 ++it;
582 }
583 }
584
585 if (removed_current_outstanding_callback) {
586 JNIEnv* env = AttachCurrentThread();
587 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
588 if (j_ref.obj()) {
589 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
590 "onGeolocationPermissionsHidePrompt");
591 Java_AwContents_onGeolocationPermissionsHidePrompt(env, j_ref);
592 }
593 if (!pending_geolocation_prompts_.empty()) {
594 ShowGeolocationPromptHelper(java_ref_,
595 pending_geolocation_prompts_.front().first);
596 }
597 }
598 }
599
600 void AwContents::OnPermissionRequest(
601 base::android::ScopedJavaLocalRef<jobject> j_request,
602 AwPermissionRequest* request) {
603 DCHECK(!j_request.is_null());
604 DCHECK(request);
605
606 JNIEnv* env = AttachCurrentThread();
607 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
608 if (j_ref.is_null()) {
609 permission_request_handler_->CancelRequest(request->GetOrigin(),
610 request->GetResources());
611 return;
612 }
613
614 Java_AwContents_onPermissionRequest(env, j_ref, j_request);
615 }
616
617 void AwContents::OnPermissionRequestCanceled(AwPermissionRequest* request) {
618 JNIEnv* env = AttachCurrentThread();
619 ScopedJavaLocalRef<jobject> j_request = request->GetJavaObject();
620 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
621 if (j_request.is_null() || j_ref.is_null())
622 return;
623
624 Java_AwContents_onPermissionRequestCanceled(env, j_ref, j_request);
625 }
626
627 void AwContents::PreauthorizePermission(JNIEnv* env,
628 const JavaParamRef<jobject>& obj,
629 const JavaParamRef<jstring>& origin,
630 jlong resources) {
631 permission_request_handler_->PreauthorizePermission(
632 GURL(base::android::ConvertJavaStringToUTF8(env, origin)), resources);
633 }
634
635 void AwContents::RequestProtectedMediaIdentifierPermission(
636 const GURL& origin,
637 const base::Callback<void(bool)>& callback) {
638 permission_request_handler_->SendRequest(
639 std::unique_ptr<AwPermissionRequestDelegate>(new SimplePermissionRequest(
640 origin, AwPermissionRequest::ProtectedMediaId, callback)));
641 }
642
643 void AwContents::CancelProtectedMediaIdentifierPermissionRequests(
644 const GURL& origin) {
645 permission_request_handler_->CancelRequest(
646 origin, AwPermissionRequest::ProtectedMediaId);
647 }
648
649 void AwContents::RequestGeolocationPermission(
650 const GURL& origin,
651 const base::Callback<void(bool)>& callback) {
652 JNIEnv* env = AttachCurrentThread();
653 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
654 if (obj.is_null())
655 return;
656
657 if (Java_AwContents_useLegacyGeolocationPermissionAPI(env, obj)) {
658 ShowGeolocationPrompt(origin, callback);
659 return;
660 }
661 permission_request_handler_->SendRequest(
662 std::unique_ptr<AwPermissionRequestDelegate>(new SimplePermissionRequest(
663 origin, AwPermissionRequest::Geolocation, callback)));
664 }
665
666 void AwContents::CancelGeolocationPermissionRequests(const GURL& origin) {
667 JNIEnv* env = AttachCurrentThread();
668 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
669 if (obj.is_null())
670 return;
671
672 if (Java_AwContents_useLegacyGeolocationPermissionAPI(env, obj)) {
673 HideGeolocationPrompt(origin);
674 return;
675 }
676 permission_request_handler_->CancelRequest(
677 origin, AwPermissionRequest::Geolocation);
678 }
679
680 void AwContents::RequestMIDISysexPermission(
681 const GURL& origin,
682 const base::Callback<void(bool)>& callback) {
683 permission_request_handler_->SendRequest(
684 std::unique_ptr<AwPermissionRequestDelegate>(new SimplePermissionRequest(
685 origin, AwPermissionRequest::MIDISysex, callback)));
686 }
687
688 void AwContents::CancelMIDISysexPermissionRequests(const GURL& origin) {
689 permission_request_handler_->CancelRequest(
690 origin, AwPermissionRequest::AwPermissionRequest::MIDISysex);
691 }
692
693 void AwContents::FindAllAsync(JNIEnv* env,
694 const JavaParamRef<jobject>& obj,
695 const JavaParamRef<jstring>& search_string) {
696 DCHECK_CURRENTLY_ON(BrowserThread::UI);
697 GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string));
698 }
699
700 void AwContents::FindNext(JNIEnv* env,
701 const JavaParamRef<jobject>& obj,
702 jboolean forward) {
703 DCHECK_CURRENTLY_ON(BrowserThread::UI);
704 GetFindHelper()->FindNext(forward);
705 }
706
707 void AwContents::ClearMatches(JNIEnv* env, const JavaParamRef<jobject>& obj) {
708 DCHECK_CURRENTLY_ON(BrowserThread::UI);
709 GetFindHelper()->ClearMatches();
710 }
711
712 void AwContents::ClearCache(JNIEnv* env,
713 const JavaParamRef<jobject>& obj,
714 jboolean include_disk_files) {
715 DCHECK_CURRENTLY_ON(BrowserThread::UI);
716 render_view_host_ext_->ClearCache();
717
718 if (include_disk_files)
719 RemoveHttpDiskCache(web_contents_->GetRenderProcessHost());
720 }
721
722 void AwContents::KillRenderProcess(JNIEnv* env,
723 const JavaParamRef<jobject>& obj) {
724 DCHECK_CURRENTLY_ON(BrowserThread::UI);
725 render_view_host_ext_->KillRenderProcess();
726 }
727
728 FindHelper* AwContents::GetFindHelper() {
729 DCHECK_CURRENTLY_ON(BrowserThread::UI);
730 if (!find_helper_.get()) {
731 find_helper_.reset(new FindHelper(web_contents_.get()));
732 find_helper_->SetListener(this);
733 }
734 return find_helper_.get();
735 }
736
737 void AwContents::OnFindResultReceived(int active_ordinal,
738 int match_count,
739 bool finished) {
740 DCHECK_CURRENTLY_ON(BrowserThread::UI);
741 JNIEnv* env = AttachCurrentThread();
742 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
743 if (obj.is_null())
744 return;
745
746 Java_AwContents_onFindResultReceived(env, obj, active_ordinal, match_count,
747 finished);
748 }
749
750 bool AwContents::ShouldDownloadFavicon(const GURL& icon_url) {
751 return g_should_download_favicons;
752 }
753
754 void AwContents::OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) {
755 DCHECK_CURRENTLY_ON(BrowserThread::UI);
756 JNIEnv* env = AttachCurrentThread();
757 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
758 if (obj.is_null())
759 return;
760
761 content::NavigationEntry* entry =
762 web_contents_->GetController().GetLastCommittedEntry();
763
764 if (entry) {
765 entry->GetFavicon().valid = true;
766 entry->GetFavicon().url = icon_url;
767 entry->GetFavicon().image = gfx::Image::CreateFrom1xBitmap(bitmap);
768 }
769
770 Java_AwContents_onReceivedIcon(env, obj, gfx::ConvertToJavaBitmap(&bitmap));
771 }
772
773 void AwContents::OnReceivedTouchIconUrl(const std::string& url,
774 bool precomposed) {
775 DCHECK_CURRENTLY_ON(BrowserThread::UI);
776 JNIEnv* env = AttachCurrentThread();
777 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
778 if (obj.is_null())
779 return;
780
781 Java_AwContents_onReceivedTouchIconUrl(
782 env, obj, ConvertUTF8ToJavaString(env, url), precomposed);
783 }
784
785 void AwContents::PostInvalidate() {
786 DCHECK_CURRENTLY_ON(BrowserThread::UI);
787 JNIEnv* env = AttachCurrentThread();
788 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
789 if (!obj.is_null())
790 Java_AwContents_postInvalidateOnAnimation(env, obj);
791 }
792
793 void AwContents::OnNewPicture() {
794 DCHECK_CURRENTLY_ON(BrowserThread::UI);
795 JNIEnv* env = AttachCurrentThread();
796 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
797 if (!obj.is_null()) {
798 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
799 "onNewPicture");
800 Java_AwContents_onNewPicture(env, obj);
801 }
802 }
803
804 base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetCertificate(
805 JNIEnv* env,
806 const JavaParamRef<jobject>& obj) {
807 DCHECK_CURRENTLY_ON(BrowserThread::UI);
808 content::NavigationEntry* entry =
809 web_contents_->GetController().GetLastCommittedEntry();
810 if (!entry || !entry->GetSSL().certificate)
811 return ScopedJavaLocalRef<jbyteArray>();
812
813 // Convert the certificate and return it
814 std::string der_string;
815 net::X509Certificate::GetDEREncoded(
816 entry->GetSSL().certificate->os_cert_handle(), &der_string);
817 return base::android::ToJavaByteArray(
818 env, reinterpret_cast<const uint8_t*>(der_string.data()),
819 der_string.length());
820 }
821
822 void AwContents::RequestNewHitTestDataAt(JNIEnv* env,
823 const JavaParamRef<jobject>& obj,
824 jfloat x,
825 jfloat y,
826 jfloat touch_major) {
827 DCHECK_CURRENTLY_ON(BrowserThread::UI);
828 gfx::PointF touch_center(x, y);
829 gfx::SizeF touch_area(touch_major, touch_major);
830 render_view_host_ext_->RequestNewHitTestDataAt(touch_center, touch_area);
831 }
832
833 void AwContents::UpdateLastHitTestData(JNIEnv* env,
834 const JavaParamRef<jobject>& obj) {
835 DCHECK_CURRENTLY_ON(BrowserThread::UI);
836 if (!render_view_host_ext_->HasNewHitTestData()) return;
837
838 const AwHitTestData& data = render_view_host_ext_->GetLastHitTestData();
839 render_view_host_ext_->MarkHitTestDataRead();
840
841 // Make sure to null the Java object if data is empty/invalid.
842 ScopedJavaLocalRef<jstring> extra_data_for_type;
843 if (data.extra_data_for_type.length())
844 extra_data_for_type = ConvertUTF8ToJavaString(
845 env, data.extra_data_for_type);
846
847 ScopedJavaLocalRef<jstring> href;
848 if (data.href.length())
849 href = ConvertUTF16ToJavaString(env, data.href);
850
851 ScopedJavaLocalRef<jstring> anchor_text;
852 if (data.anchor_text.length())
853 anchor_text = ConvertUTF16ToJavaString(env, data.anchor_text);
854
855 ScopedJavaLocalRef<jstring> img_src;
856 if (data.img_src.is_valid())
857 img_src = ConvertUTF8ToJavaString(env, data.img_src.spec());
858
859 Java_AwContents_updateHitTestData(env, obj, data.type, extra_data_for_type,
860 href, anchor_text, img_src);
861 }
862
863 void AwContents::OnSizeChanged(JNIEnv* env,
864 const JavaParamRef<jobject>& obj,
865 int w,
866 int h,
867 int ow,
868 int oh) {
869 DCHECK_CURRENTLY_ON(BrowserThread::UI);
870 browser_view_renderer_.OnSizeChanged(w, h);
871 }
872
873 void AwContents::SetViewVisibility(JNIEnv* env,
874 const JavaParamRef<jobject>& obj,
875 bool visible) {
876 DCHECK_CURRENTLY_ON(BrowserThread::UI);
877 browser_view_renderer_.SetViewVisibility(visible);
878 UpdateRendererPriority();
879 }
880
881 void AwContents::SetWindowVisibility(JNIEnv* env,
882 const JavaParamRef<jobject>& obj,
883 bool visible) {
884 DCHECK_CURRENTLY_ON(BrowserThread::UI);
885 browser_view_renderer_.SetWindowVisibility(visible);
886 UpdateRendererPriority();
887 }
888
889 void AwContents::SetIsPaused(JNIEnv* env,
890 const JavaParamRef<jobject>& obj,
891 bool paused) {
892 DCHECK_CURRENTLY_ON(BrowserThread::UI);
893 browser_view_renderer_.SetIsPaused(paused);
894 UpdateRendererPriority();
895 }
896
897 void AwContents::OnAttachedToWindow(JNIEnv* env,
898 const JavaParamRef<jobject>& obj,
899 int w,
900 int h) {
901 DCHECK_CURRENTLY_ON(BrowserThread::UI);
902 browser_view_renderer_.OnAttachedToWindow(w, h);
903 UpdateRendererPriority();
904 }
905
906 void AwContents::OnDetachedFromWindow(JNIEnv* env,
907 const JavaParamRef<jobject>& obj) {
908 DCHECK_CURRENTLY_ON(BrowserThread::UI);
909 browser_view_renderer_.OnDetachedFromWindow();
910 UpdateRendererPriority();
911 }
912
913 bool AwContents::IsVisible(JNIEnv* env, const JavaParamRef<jobject>& obj) {
914 return browser_view_renderer_.IsClientVisible();
915 }
916
917 base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetOpaqueState(
918 JNIEnv* env,
919 const JavaParamRef<jobject>& obj) {
920 DCHECK_CURRENTLY_ON(BrowserThread::UI);
921 // Required optimization in WebViewClassic to not save any state if
922 // there has been no navigations.
923 if (!web_contents_->GetController().GetEntryCount())
924 return ScopedJavaLocalRef<jbyteArray>();
925
926 base::Pickle pickle;
927 if (!WriteToPickle(*web_contents_, &pickle)) {
928 return ScopedJavaLocalRef<jbyteArray>();
929 } else {
930 return base::android::ToJavaByteArray(
931 env, reinterpret_cast<const uint8_t*>(pickle.data()), pickle.size());
932 }
933 }
934
935 jboolean AwContents::RestoreFromOpaqueState(
936 JNIEnv* env,
937 const JavaParamRef<jobject>& obj,
938 const JavaParamRef<jbyteArray>& state) {
939 DCHECK_CURRENTLY_ON(BrowserThread::UI);
940 // TODO(boliu): This copy can be optimized out if this is a performance
941 // problem.
942 std::vector<uint8_t> state_vector;
943 base::android::JavaByteArrayToByteVector(env, state, &state_vector);
944
945 base::Pickle pickle(reinterpret_cast<const char*>(state_vector.data()),
946 state_vector.size());
947 base::PickleIterator iterator(pickle);
948
949 return RestoreFromPickle(&iterator, web_contents_.get());
950 }
951
952 bool AwContents::OnDraw(JNIEnv* env,
953 const JavaParamRef<jobject>& obj,
954 const JavaParamRef<jobject>& canvas,
955 jboolean is_hardware_accelerated,
956 jint scroll_x,
957 jint scroll_y,
958 jint visible_left,
959 jint visible_top,
960 jint visible_right,
961 jint visible_bottom) {
962 DCHECK_CURRENTLY_ON(BrowserThread::UI);
963 gfx::Vector2d scroll(scroll_x, scroll_y);
964 browser_view_renderer_.PrepareToDraw(
965 scroll, gfx::Rect(visible_left, visible_top, visible_right - visible_left,
966 visible_bottom - visible_top));
967 if (is_hardware_accelerated && browser_view_renderer_.attached_to_window() &&
968 !g_force_auxiliary_bitmap_rendering) {
969 return browser_view_renderer_.OnDrawHardware();
970 }
971
972 gfx::Size view_size = browser_view_renderer_.size();
973 if (view_size.IsEmpty()) {
974 TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_EmptySize",
975 TRACE_EVENT_SCOPE_THREAD);
976 return false;
977 }
978
979 // TODO(hush): Right now webview size is passed in as the auxiliary bitmap
980 // size, which might hurt performace (only for software draws with auxiliary
981 // bitmap). For better performance, get global visible rect, transform it
982 // from screen space to view space, then intersect with the webview in
983 // viewspace. Use the resulting rect as the auxiliary bitmap.
984 std::unique_ptr<SoftwareCanvasHolder> canvas_holder =
985 SoftwareCanvasHolder::Create(canvas, scroll, view_size,
986 g_force_auxiliary_bitmap_rendering);
987 if (!canvas_holder || !canvas_holder->GetCanvas()) {
988 TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoSoftwareCanvas",
989 TRACE_EVENT_SCOPE_THREAD);
990 return false;
991 }
992 return browser_view_renderer_.OnDrawSoftware(canvas_holder->GetCanvas());
993 }
994
995 void AwContents::SetPendingWebContentsForPopup(
996 std::unique_ptr<content::WebContents> pending) {
997 DCHECK_CURRENTLY_ON(BrowserThread::UI);
998 if (pending_contents_.get()) {
999 // TODO(benm): Support holding multiple pop up window requests.
1000 LOG(WARNING) << "Blocking popup window creation as an outstanding "
1001 << "popup window is still pending.";
1002 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
1003 pending.release());
1004 return;
1005 }
1006 pending_contents_.reset(new AwContents(std::move(pending)));
1007 // Set dip_scale for pending contents, which is necessary for the later
1008 // SynchronousCompositor and InputHandler setup.
1009 pending_contents_->SetDipScaleInternal(browser_view_renderer_.dip_scale());
1010 }
1011
1012 void AwContents::FocusFirstNode(JNIEnv* env, const JavaParamRef<jobject>& obj) {
1013 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1014 web_contents_->FocusThroughTabTraversal(false);
1015 }
1016
1017 void AwContents::SetBackgroundColor(JNIEnv* env,
1018 const JavaParamRef<jobject>& obj,
1019 jint color) {
1020 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1021 render_view_host_ext_->SetBackgroundColor(color);
1022 }
1023
1024 void AwContents::ZoomBy(JNIEnv* env,
1025 const base::android::JavaParamRef<jobject>& obj,
1026 jfloat delta) {
1027 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1028 browser_view_renderer_.ZoomBy(delta);
1029 }
1030
1031 void AwContents::OnComputeScroll(JNIEnv* env,
1032 const JavaParamRef<jobject>& obj,
1033 jlong animation_time_millis) {
1034 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1035 browser_view_renderer_.OnComputeScroll(
1036 base::TimeTicks() +
1037 base::TimeDelta::FromMilliseconds(animation_time_millis));
1038 }
1039
1040 jlong AwContents::ReleasePopupAwContents(JNIEnv* env,
1041 const JavaParamRef<jobject>& obj) {
1042 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1043 return reinterpret_cast<intptr_t>(pending_contents_.release());
1044 }
1045
1046 gfx::Point AwContents::GetLocationOnScreen() {
1047 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1048 JNIEnv* env = AttachCurrentThread();
1049 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1050 if (obj.is_null())
1051 return gfx::Point();
1052 std::vector<int> location;
1053 base::android::JavaIntArrayToIntVector(
1054 env, Java_AwContents_getLocationOnScreen(env, obj).obj(), &location);
1055 return gfx::Point(location[0], location[1]);
1056 }
1057
1058 void AwContents::ScrollContainerViewTo(const gfx::Vector2d& new_value) {
1059 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1060 JNIEnv* env = AttachCurrentThread();
1061 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1062 if (obj.is_null())
1063 return;
1064 Java_AwContents_scrollContainerViewTo(env, obj, new_value.x(), new_value.y());
1065 }
1066
1067 void AwContents::UpdateScrollState(const gfx::Vector2d& max_scroll_offset,
1068 const gfx::SizeF& contents_size_dip,
1069 float page_scale_factor,
1070 float min_page_scale_factor,
1071 float max_page_scale_factor) {
1072 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1073 JNIEnv* env = AttachCurrentThread();
1074 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1075 if (obj.is_null())
1076 return;
1077 Java_AwContents_updateScrollState(
1078 env, obj, max_scroll_offset.x(), max_scroll_offset.y(),
1079 contents_size_dip.width(), contents_size_dip.height(), page_scale_factor,
1080 min_page_scale_factor, max_page_scale_factor);
1081 }
1082
1083 void AwContents::DidOverscroll(const gfx::Vector2d& overscroll_delta,
1084 const gfx::Vector2dF& overscroll_velocity) {
1085 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1086 JNIEnv* env = AttachCurrentThread();
1087 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1088 if (obj.is_null())
1089 return;
1090 Java_AwContents_didOverscroll(env, obj, overscroll_delta.x(),
1091 overscroll_delta.y(), overscroll_velocity.x(),
1092 overscroll_velocity.y());
1093 }
1094
1095 ui::TouchHandleDrawable* AwContents::CreateDrawable() {
1096 JNIEnv* env = AttachCurrentThread();
1097 const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1098 if (obj.is_null())
1099 return nullptr;
1100 return reinterpret_cast<ui::TouchHandleDrawable*>(
1101 Java_AwContents_onCreateTouchHandle(env, obj));
1102 }
1103
1104 void AwContents::SetDipScale(JNIEnv* env,
1105 const JavaParamRef<jobject>& obj,
1106 jfloat dip_scale) {
1107 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1108 SetDipScaleInternal(dip_scale);
1109 }
1110
1111 void AwContents::SetDipScaleInternal(float dip_scale) {
1112 browser_view_renderer_.SetDipScale(dip_scale);
1113 }
1114
1115 void AwContents::ScrollTo(JNIEnv* env,
1116 const JavaParamRef<jobject>& obj,
1117 jint x,
1118 jint y) {
1119 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1120 browser_view_renderer_.ScrollTo(gfx::Vector2d(x, y));
1121 }
1122
1123 void AwContents::SmoothScroll(JNIEnv* env,
1124 const JavaParamRef<jobject>& obj,
1125 jint target_x,
1126 jint target_y,
1127 jlong duration_ms) {
1128 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1129
1130 float scale = browser_view_renderer_.dip_scale() *
1131 browser_view_renderer_.page_scale_factor();
1132 render_view_host_ext_->SmoothScroll(target_x / scale, target_y / scale,
1133 duration_ms);
1134 }
1135
1136 void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) {
1137 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1138 JNIEnv* env = AttachCurrentThread();
1139 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1140 if (obj.is_null())
1141 return;
1142 Java_AwContents_onWebLayoutPageScaleFactorChanged(env, obj,
1143 page_scale_factor);
1144 }
1145
1146 void AwContents::OnWebLayoutContentsSizeChanged(
1147 const gfx::Size& contents_size) {
1148 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1149 JNIEnv* env = AttachCurrentThread();
1150 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1151 if (obj.is_null())
1152 return;
1153 Java_AwContents_onWebLayoutContentsSizeChanged(
1154 env, obj, contents_size.width(), contents_size.height());
1155 }
1156
1157 jlong AwContents::CapturePicture(JNIEnv* env,
1158 const JavaParamRef<jobject>& obj,
1159 int width,
1160 int height) {
1161 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1162 return reinterpret_cast<intptr_t>(
1163 new AwPicture(browser_view_renderer_.CapturePicture(width, height)));
1164 }
1165
1166 void AwContents::EnableOnNewPicture(JNIEnv* env,
1167 const JavaParamRef<jobject>& obj,
1168 jboolean enabled) {
1169 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1170 browser_view_renderer_.EnableOnNewPicture(enabled);
1171 }
1172
1173 namespace {
1174 void InvokeVisualStateCallback(const JavaObjectWeakGlobalRef& java_ref,
1175 jlong request_id,
1176 const JavaRef<jobject>& callback,
1177 bool result) {
1178 JNIEnv* env = AttachCurrentThread();
1179 ScopedJavaLocalRef<jobject> obj = java_ref.get(env);
1180 if (obj.is_null())
1181 return;
1182 Java_AwContents_invokeVisualStateCallback(env, obj, callback, request_id);
1183 }
1184 } // namespace
1185
1186 void AwContents::InsertVisualStateCallback(
1187 JNIEnv* env,
1188 const JavaParamRef<jobject>& obj,
1189 jlong request_id,
1190 const JavaParamRef<jobject>& callback) {
1191 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1192 web_contents_->GetMainFrame()->InsertVisualStateCallback(
1193 base::Bind(&InvokeVisualStateCallback, java_ref_, request_id,
1194 ScopedJavaGlobalRef<jobject>(env, callback)));
1195 }
1196
1197 void AwContents::UpdateRendererPriority(
1198 AwRendererPriorityManager::RendererPriority base_priority) {
1199 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1200 content::RenderProcessHost* rph = web_contents_->GetRenderProcessHost();
1201 AwRendererPriorityManager::RendererPriority computed_priority = base_priority;
1202
1203 std::unique_ptr<content::RenderWidgetHostIterator> widgets(
1204 content::RenderWidgetHost::GetRenderWidgetHosts());
1205 content::RenderWidgetHost* widget;
1206 while ((widget = widgets->GetNextHost()) != nullptr &&
1207 computed_priority <
1208 AwRendererPriorityManager::RENDERER_PRIORITY_HIGH) {
1209 content::RenderViewHost* view = content::RenderViewHost::From(widget);
1210 if (view && rph == view->GetProcess()) {
1211 content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
1212 if (wc && wc != web_contents_.get()) {
1213 AwContents* aw_contents = FromWebContents(wc);
1214 if (aw_contents) {
1215 computed_priority = std::max(
1216 aw_contents->GetComputedRendererPriority(), computed_priority);
1217 }
1218 }
1219 }
1220 }
1221 GetAwRendererPriorityManager()->SetRendererPriority(computed_priority);
1222 }
1223
1224 AwRendererPriorityManager::RendererPriority
1225 AwContents::GetComputedRendererPriority() {
1226 if (renderer_priority_waived_when_not_visible_ &&
1227 !browser_view_renderer_.IsClientVisible()) {
1228 return AwRendererPriorityManager::RENDERER_PRIORITY_WAIVED;
1229 }
1230 return renderer_requested_priority_;
1231 }
1232
1233 void AwContents::UpdateRendererPriority() {
1234 UpdateRendererPriority(GetComputedRendererPriority());
1235 }
1236
1237 AwRendererPriorityManager* AwContents::GetAwRendererPriorityManager() {
1238 content::RenderProcessHost* rph = web_contents_->GetRenderProcessHost();
1239 AwRendererPriorityManager* manager = static_cast<AwRendererPriorityManager*>(
1240 rph->GetUserData(kComputedRendererPriorityUserDataKey));
1241 if (manager == nullptr) {
1242 manager = new AwRendererPriorityManager(rph);
1243 rph->SetUserData(kComputedRendererPriorityUserDataKey,
1244 base::WrapUnique(manager));
1245 }
1246 return manager;
1247 }
1248
1249 AwRendererPriorityManager::RendererPriority
1250 AwContents::GetCurrentRendererPriority() {
1251 return GetAwRendererPriorityManager()->GetRendererPriority();
1252 }
1253
1254 jint AwContents::GetRendererCurrentPriority(
1255 JNIEnv* env,
1256 const base::android::JavaParamRef<jobject>& obj) {
1257 return GetCurrentRendererPriority();
1258 }
1259
1260 jint AwContents::GetRendererRequestedPriority(
1261 JNIEnv* env,
1262 const base::android::JavaParamRef<jobject>& obj) {
1263 return renderer_requested_priority_;
1264 }
1265
1266 jboolean AwContents::GetRendererPriorityWaivedWhenNotVisible(
1267 JNIEnv* env,
1268 const base::android::JavaParamRef<jobject>& obj) {
1269 return renderer_priority_waived_when_not_visible_;
1270 }
1271
1272 void AwContents::SetRendererPriorityPolicy(
1273 JNIEnv* env,
1274 const JavaParamRef<jobject>& obj,
1275 jint renderer_requested_priority,
1276 jboolean renderer_priority_waived_when_not_visible) {
1277 renderer_requested_priority_ =
1278 static_cast<AwRendererPriorityManager::RendererPriority>(
1279 renderer_requested_priority);
1280 renderer_priority_waived_when_not_visible_ =
1281 renderer_priority_waived_when_not_visible;
1282 UpdateRendererPriority(renderer_requested_priority_);
1283 }
1284
1285 void AwContents::ClearView(JNIEnv* env, const JavaParamRef<jobject>& obj) {
1286 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1287 browser_view_renderer_.ClearView();
1288 }
1289
1290 void AwContents::SetExtraHeadersForUrl(
1291 JNIEnv* env,
1292 const JavaParamRef<jobject>& obj,
1293 const JavaParamRef<jstring>& url,
1294 const JavaParamRef<jstring>& jextra_headers) {
1295 std::string extra_headers;
1296 if (jextra_headers)
1297 extra_headers = ConvertJavaStringToUTF8(env, jextra_headers);
1298 AwResourceContext* resource_context = static_cast<AwResourceContext*>(
1299 AwBrowserContext::FromWebContents(web_contents_.get())->
1300 GetResourceContext());
1301 resource_context->SetExtraHeaders(GURL(ConvertJavaStringToUTF8(env, url)),
1302 extra_headers);
1303 }
1304
1305 void AwContents::SetJsOnlineProperty(JNIEnv* env,
1306 const JavaParamRef<jobject>& obj,
1307 jboolean network_up) {
1308 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1309 render_view_host_ext_->SetJsOnlineProperty(network_up);
1310 }
1311
1312 void AwContents::TrimMemory(JNIEnv* env,
1313 const JavaParamRef<jobject>& obj,
1314 jint level,
1315 jboolean visible) {
1316 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1317 // Constants from Android ComponentCallbacks2.
1318 enum {
1319 TRIM_MEMORY_RUNNING_LOW = 10,
1320 TRIM_MEMORY_UI_HIDDEN = 20,
1321 TRIM_MEMORY_BACKGROUND = 40,
1322 TRIM_MEMORY_MODERATE = 60,
1323 };
1324
1325 // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
1326 // it does not indicate memory pressure, but merely that the app is
1327 // backgrounded.
1328 if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
1329 return;
1330
1331 // Do not release resources on view we expect to get DrawGL soon.
1332 if (level < TRIM_MEMORY_BACKGROUND && visible)
1333 return;
1334
1335 browser_view_renderer_.TrimMemory();
1336 }
1337
1338 // TODO(sgurun) add support for posting a frame whose name is known (only
1339 // main frame is supported at this time, see crbug.com/389721)
1340 void AwContents::PostMessageToFrame(JNIEnv* env,
1341 const JavaParamRef<jobject>& obj,
1342 const JavaParamRef<jstring>& frame_name,
1343 const JavaParamRef<jstring>& message,
1344 const JavaParamRef<jstring>& target_origin,
1345 const JavaParamRef<jobjectArray>& ports) {
1346 // Use an empty source origin for android webview.
1347 content::MessagePortProvider::PostMessageToFrame(web_contents_.get(),
1348 env,
1349 nullptr,
1350 target_origin,
1351 message,
1352 ports);
1353 }
1354
1355 void AwContents::GrantFileSchemeAccesstoChildProcess(
1356 JNIEnv* env,
1357 const JavaParamRef<jobject>& obj) {
1358 content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
1359 web_contents_->GetRenderProcessHost()->GetID(), url::kFileScheme);
1360 }
1361
1362 void AwContents::ResumeLoadingCreatedPopupWebContents(
1363 JNIEnv* env,
1364 const JavaParamRef<jobject>& obj) {
1365 web_contents_->ResumeLoadingCreatedWebContents();
1366 }
1367
1368 void SetShouldDownloadFavicons(JNIEnv* env,
1369 const JavaParamRef<jclass>& jclazz) {
1370 g_should_download_favicons = true;
1371 }
1372
1373 void AwContents::RenderViewHostChanged(content::RenderViewHost* old_host,
1374 content::RenderViewHost* new_host) {
1375 DCHECK(new_host);
1376
1377 int process_id = new_host->GetProcess()->GetID();
1378 int routing_id = new_host->GetRoutingID();
1379
1380 // At this point, the current RVH may or may not contain a compositor. So
1381 // compositor_ may be nullptr, in which case
1382 // BrowserViewRenderer::DidInitializeCompositor() callback is time when the
1383 // new compositor is constructed.
1384 browser_view_renderer_.SetActiveCompositorID(
1385 CompositorID(process_id, routing_id));
1386 }
1387
1388 void AwContents::DidAttachInterstitialPage() {
1389 CompositorID compositor_id;
1390 RenderFrameHost* rfh = web_contents_->GetInterstitialPage()->GetMainFrame();
1391 compositor_id.process_id = rfh->GetProcess()->GetID();
1392 compositor_id.routing_id = rfh->GetRenderViewHost()->GetRoutingID();
1393 browser_view_renderer_.SetActiveCompositorID(compositor_id);
1394 }
1395
1396 void AwContents::DidDetachInterstitialPage() {
1397 CompositorID compositor_id;
1398 if (!web_contents_)
1399 return;
1400 if (web_contents_->GetRenderProcessHost() &&
1401 web_contents_->GetRenderViewHost()) {
1402 compositor_id.process_id = web_contents_->GetRenderProcessHost()->GetID();
1403 compositor_id.routing_id =
1404 web_contents_->GetRenderViewHost()->GetRoutingID();
1405 } else {
1406 LOG(WARNING) << "failed setting the compositor on detaching interstitital";
1407 }
1408 browser_view_renderer_.SetActiveCompositorID(compositor_id);
1409 }
1410
1411 bool AwContents::CanShowBigInterstitial() {
1412 JNIEnv* env = AttachCurrentThread();
1413 const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1414 if (obj.is_null())
1415 return false;
1416 return Java_AwContents_canShowBigInterstitial(env, obj);
1417 }
1418
1419 void AwContents::CallProceedOnInterstitialForTesting(
1420 JNIEnv* env,
1421 const base::android::JavaParamRef<jobject>& obj) {
1422 DCHECK(web_contents_->GetInterstitialPage());
1423 web_contents_->GetInterstitialPage()->Proceed();
1424 }
1425
1426 void AwContents::CallDontProceedOnInterstitialForTesting(
1427 JNIEnv* env,
1428 const base::android::JavaParamRef<jobject>& obj) {
1429 DCHECK(web_contents_->GetInterstitialPage());
1430 web_contents_->GetInterstitialPage()->DontProceed();
1431 }
1432
1433 void AwContents::OnRenderProcessGone(int child_process_id) {
1434 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1435 JNIEnv* env = AttachCurrentThread();
1436 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1437 if (obj.is_null())
1438 return;
1439
1440 Java_AwContents_onRenderProcessGone(env, obj, child_process_id);
1441 }
1442
1443 bool AwContents::OnRenderProcessGoneDetail(int child_process_id,
1444 bool crashed) {
1445 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1446 JNIEnv* env = AttachCurrentThread();
1447 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
1448 if (obj.is_null())
1449 return false;
1450
1451 return Java_AwContents_onRenderProcessGoneDetail(env, obj,
1452 child_process_id, crashed);
1453 }
1454
1455 void AwContents::RenderProcessReady(content::RenderProcessHost* host) {
1456 UpdateRendererPriority();
1457 }
1458
1459 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698