Revert of Update WV test license server config to use portable sdk server. (https...
[chromium-blink-merge.git] / android_webview / native / aw_contents.cc
blob2b35fc5aaffad419117e22986cfa0db6fc7a5835
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.
5 #include "android_webview/native/aw_contents.h"
7 #include <limits>
9 #include "android_webview/browser/aw_browser_context.h"
10 #include "android_webview/browser/aw_browser_main_parts.h"
11 #include "android_webview/browser/aw_resource_context.h"
12 #include "android_webview/browser/browser_view_renderer.h"
13 #include "android_webview/browser/gpu_memory_buffer_factory_impl.h"
14 #include "android_webview/browser/net_disk_cache_remover.h"
15 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
16 #include "android_webview/common/aw_hit_test_data.h"
17 #include "android_webview/common/devtools_instrumentation.h"
18 #include "android_webview/native/aw_autofill_manager_delegate.h"
19 #include "android_webview/native/aw_browser_dependency_factory.h"
20 #include "android_webview/native/aw_contents_client_bridge.h"
21 #include "android_webview/native/aw_contents_io_thread_client_impl.h"
22 #include "android_webview/native/aw_pdf_exporter.h"
23 #include "android_webview/native/aw_picture.h"
24 #include "android_webview/native/aw_web_contents_delegate.h"
25 #include "android_webview/native/java_browser_view_renderer_helper.h"
26 #include "android_webview/native/state_serializer.h"
27 #include "android_webview/public/browser/draw_gl.h"
28 #include "base/android/jni_android.h"
29 #include "base/android/jni_array.h"
30 #include "base/android/jni_string.h"
31 #include "base/android/scoped_java_ref.h"
32 #include "base/atomicops.h"
33 #include "base/bind.h"
34 #include "base/callback.h"
35 #include "base/memory/memory_pressure_listener.h"
36 #include "base/message_loop/message_loop.h"
37 #include "base/pickle.h"
38 #include "base/strings/string16.h"
39 #include "base/supports_user_data.h"
40 #include "components/autofill/content/browser/autofill_driver_impl.h"
41 #include "components/autofill/core/browser/autofill_manager.h"
42 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
43 #include "components/navigation_interception/intercept_navigation_delegate.h"
44 #include "content/public/browser/android/content_view_core.h"
45 #include "content/public/browser/browser_thread.h"
46 #include "content/public/browser/cert_store.h"
47 #include "content/public/browser/favicon_status.h"
48 #include "content/public/browser/navigation_entry.h"
49 #include "content/public/browser/render_frame_host.h"
50 #include "content/public/browser/render_process_host.h"
51 #include "content/public/browser/render_view_host.h"
52 #include "content/public/browser/web_contents.h"
53 #include "content/public/common/renderer_preferences.h"
54 #include "content/public/common/ssl_status.h"
55 #include "jni/AwContents_jni.h"
56 #include "net/cert/x509_certificate.h"
57 #include "third_party/skia/include/core/SkPicture.h"
58 #include "ui/base/l10n/l10n_util_android.h"
59 #include "ui/gfx/android/java_bitmap.h"
60 #include "ui/gfx/font_render_params_linux.h"
61 #include "ui/gfx/image/image.h"
62 #include "ui/gfx/size.h"
64 struct AwDrawSWFunctionTable;
65 struct AwDrawGLFunctionTable;
67 using autofill::AutofillDriverImpl;
68 using autofill::AutofillManager;
69 using base::android::AttachCurrentThread;
70 using base::android::ConvertJavaStringToUTF16;
71 using base::android::ConvertJavaStringToUTF8;
72 using base::android::ConvertUTF16ToJavaString;
73 using base::android::ConvertUTF8ToJavaString;
74 using base::android::JavaRef;
75 using base::android::ScopedJavaGlobalRef;
76 using base::android::ScopedJavaLocalRef;
77 using navigation_interception::InterceptNavigationDelegate;
78 using content::BrowserThread;
79 using content::ContentViewCore;
80 using content::WebContents;
82 extern "C" {
83 static AwDrawGLFunction DrawGLFunction;
84 static void DrawGLFunction(int view_context,
85 AwDrawGLInfo* draw_info,
86 void* spare) {
87 // |view_context| is the value that was returned from the java
88 // AwContents.onPrepareDrawGL; this cast must match the code there.
89 reinterpret_cast<android_webview::BrowserViewRenderer*>(view_context)->DrawGL(
90 draw_info);
94 namespace android_webview {
96 namespace {
98 bool g_should_download_favicons = false;
100 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey;
102 class AwContentsUserData : public base::SupportsUserData::Data {
103 public:
104 AwContentsUserData(AwContents* ptr) : contents_(ptr) {}
106 static AwContents* GetContents(WebContents* web_contents) {
107 if (!web_contents)
108 return NULL;
109 AwContentsUserData* data = reinterpret_cast<AwContentsUserData*>(
110 web_contents->GetUserData(kAwContentsUserDataKey));
111 return data ? data->contents_ : NULL;
114 private:
115 AwContents* contents_;
118 base::subtle::Atomic32 g_instance_count = 0;
120 // TODO(boliu): Deduplicate with chrome/ code.
121 content::RendererPreferencesHintingEnum GetRendererPreferencesHintingEnum(
122 gfx::FontRenderParams::Hinting hinting) {
123 switch (hinting) {
124 case gfx::FontRenderParams::HINTING_NONE:
125 return content::RENDERER_PREFERENCES_HINTING_NONE;
126 case gfx::FontRenderParams::HINTING_SLIGHT:
127 return content::RENDERER_PREFERENCES_HINTING_SLIGHT;
128 case gfx::FontRenderParams::HINTING_MEDIUM:
129 return content::RENDERER_PREFERENCES_HINTING_MEDIUM;
130 case gfx::FontRenderParams::HINTING_FULL:
131 return content::RENDERER_PREFERENCES_HINTING_FULL;
132 default:
133 NOTREACHED() << "Unhandled hinting style " << hinting;
134 return content::RENDERER_PREFERENCES_HINTING_SYSTEM_DEFAULT;
138 // TODO(boliu): Deduplicate with chrome/ code.
139 content::RendererPreferencesSubpixelRenderingEnum
140 GetRendererPreferencesSubpixelRenderingEnum(
141 gfx::FontRenderParams::SubpixelRendering subpixel_rendering) {
142 switch (subpixel_rendering) {
143 case gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE:
144 return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_NONE;
145 case gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB:
146 return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_RGB;
147 case gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR:
148 return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_BGR;
149 case gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB:
150 return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VRGB;
151 case gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR:
152 return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VBGR;
153 default:
154 NOTREACHED() << "Unhandled subpixel rendering style "
155 << subpixel_rendering;
156 return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_SYSTEM_DEFAULT;
160 void OnIoThreadClientReady(content::RenderFrameHost* rfh) {
161 int render_process_id = rfh->GetProcess()->GetID();
162 int render_frame_id = rfh->GetRoutingID();
163 AwResourceDispatcherHostDelegate::OnIoThreadClientReady(
164 render_process_id, render_frame_id);
167 } // namespace
169 // static
170 AwContents* AwContents::FromWebContents(WebContents* web_contents) {
171 return AwContentsUserData::GetContents(web_contents);
174 // static
175 AwContents* AwContents::FromID(int render_process_id, int render_view_id) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
177 const content::RenderViewHost* rvh =
178 content::RenderViewHost::FromID(render_process_id, render_view_id);
179 if (!rvh) return NULL;
180 content::WebContents* web_contents =
181 content::WebContents::FromRenderViewHost(rvh);
182 if (!web_contents) return NULL;
183 return FromWebContents(web_contents);
186 AwContents::AwContents(scoped_ptr<WebContents> web_contents)
187 : web_contents_(web_contents.Pass()),
188 shared_renderer_state_(
189 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
190 this),
191 browser_view_renderer_(this,
192 &shared_renderer_state_,
193 web_contents_.get()) {
194 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
195 icon_helper_.reset(new IconHelper(web_contents_.get()));
196 icon_helper_->SetListener(this);
197 web_contents_->SetUserData(kAwContentsUserDataKey,
198 new AwContentsUserData(this));
199 render_view_host_ext_.reset(
200 new AwRenderViewHostExt(this, web_contents_.get()));
202 AwAutofillManagerDelegate* autofill_manager_delegate =
203 AwAutofillManagerDelegate::FromWebContents(web_contents_.get());
204 if (autofill_manager_delegate)
205 InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
207 SetAndroidWebViewRendererPrefs();
210 void AwContents::SetJavaPeers(JNIEnv* env,
211 jobject obj,
212 jobject aw_contents,
213 jobject web_contents_delegate,
214 jobject contents_client_bridge,
215 jobject io_thread_client,
216 jobject intercept_navigation_delegate) {
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
218 // The |aw_content| param is technically spurious as it duplicates |obj| but
219 // is passed over anyway to make the binding more explicit.
220 java_ref_ = JavaObjectWeakGlobalRef(env, aw_contents);
222 web_contents_delegate_.reset(
223 new AwWebContentsDelegate(env, web_contents_delegate));
224 web_contents_->SetDelegate(web_contents_delegate_.get());
226 contents_client_bridge_.reset(
227 new AwContentsClientBridge(env, contents_client_bridge));
228 AwContentsClientBridgeBase::Associate(web_contents_.get(),
229 contents_client_bridge_.get());
231 AwContentsIoThreadClientImpl::Associate(
232 web_contents_.get(), ScopedJavaLocalRef<jobject>(env, io_thread_client));
234 InterceptNavigationDelegate::Associate(
235 web_contents_.get(),
236 make_scoped_ptr(new InterceptNavigationDelegate(
237 env, intercept_navigation_delegate)));
239 // Finally, having setup the associations, release any deferred requests
240 web_contents_->ForEachFrame(base::Bind(&OnIoThreadClientReady));
243 void AwContents::SetSaveFormData(bool enabled) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
245 InitAutofillIfNecessary(enabled);
246 // We need to check for the existence, since autofill_manager_delegate
247 // may not be created when the setting is false.
248 if (AutofillDriverImpl::FromWebContents(web_contents_.get())) {
249 AwAutofillManagerDelegate::FromWebContents(web_contents_.get())->
250 SetSaveFormData(enabled);
254 void AwContents::InitAutofillIfNecessary(bool enabled) {
255 // Do not initialize if the feature is not enabled.
256 if (!enabled)
257 return;
258 // Check if the autofill driver already exists.
259 content::WebContents* web_contents = web_contents_.get();
260 if (AutofillDriverImpl::FromWebContents(web_contents))
261 return;
263 AwBrowserContext::FromWebContents(web_contents)->
264 CreateUserPrefServiceIfNecessary();
265 AwAutofillManagerDelegate::CreateForWebContents(web_contents);
266 AutofillDriverImpl::CreateForWebContentsAndDelegate(
267 web_contents,
268 AwAutofillManagerDelegate::FromWebContents(web_contents),
269 l10n_util::GetDefaultLocale(),
270 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
273 void AwContents::SetAndroidWebViewRendererPrefs() {
274 content::RendererPreferences* prefs =
275 web_contents_->GetMutableRendererPrefs();
276 prefs->tap_multiple_targets_strategy =
277 content::TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
279 // TODO(boliu): Deduplicate with chrome/ code.
280 const gfx::FontRenderParams& params = gfx::GetDefaultWebKitFontRenderParams();
281 prefs->should_antialias_text = params.antialiasing;
282 prefs->use_subpixel_positioning = params.subpixel_positioning;
283 prefs->hinting = GetRendererPreferencesHintingEnum(params.hinting);
284 prefs->use_autohinter = params.autohinter;
285 prefs->use_bitmaps = params.use_bitmaps;
286 prefs->subpixel_rendering =
287 GetRendererPreferencesSubpixelRenderingEnum(params.subpixel_rendering);
289 content::RenderViewHost* host = web_contents_->GetRenderViewHost();
290 if (host)
291 host->SyncRendererPrefs();
294 void AwContents::SetAwAutofillManagerDelegate(jobject delegate) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
296 JNIEnv* env = AttachCurrentThread();
297 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
298 if (obj.is_null())
299 return;
300 Java_AwContents_setAwAutofillManagerDelegate(env, obj.obj(), delegate);
303 AwContents::~AwContents() {
304 DCHECK(AwContents::FromWebContents(web_contents_.get()) == this);
305 web_contents_->RemoveUserData(kAwContentsUserDataKey);
306 if (find_helper_.get())
307 find_helper_->SetListener(NULL);
308 if (icon_helper_.get())
309 icon_helper_->SetListener(NULL);
310 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1);
311 // When the last WebView is destroyed free all discardable memory allocated by
312 // Chromium, because the app process may continue to run for a long time
313 // without ever using another WebView.
314 if (base::subtle::NoBarrier_Load(&g_instance_count) == 0) {
315 base::MemoryPressureListener::NotifyMemoryPressure(
316 base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
320 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) {
321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
322 DCHECK(web_contents_);
323 return reinterpret_cast<jint>(web_contents_.get());
326 void AwContents::Destroy(JNIEnv* env, jobject obj) {
327 java_ref_.reset();
328 // We do not delete AwContents immediately. Some applications try to delete
329 // Webview in ShouldOverrideUrlLoading callback, which is a sync IPC from
330 // Webkit.
331 BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
334 static jlong Init(JNIEnv* env, jclass, jobject browser_context) {
335 // TODO(joth): Use |browser_context| to get the native BrowserContext, rather
336 // than hard-code the default instance lookup here.
337 scoped_ptr<WebContents> web_contents(content::WebContents::Create(
338 content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
339 // Return an 'uninitialized' instance; most work is deferred until the
340 // subsequent SetJavaPeers() call.
341 return reinterpret_cast<intptr_t>(new AwContents(web_contents.Pass()));
344 static void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) {
345 JavaBrowserViewRendererHelper::SetAwDrawSWFunctionTable(
346 reinterpret_cast<AwDrawSWFunctionTable*>(function_table));
349 static void SetAwDrawGLFunctionTable(JNIEnv* env, jclass, jint function_table) {
350 GpuMemoryBufferFactoryImpl::SetAwDrawGLFunctionTable(
351 reinterpret_cast<AwDrawGLFunctionTable*>(function_table));
354 static jint GetAwDrawGLFunction(JNIEnv* env, jclass) {
355 return reinterpret_cast<jint>(&DrawGLFunction);
358 // static
359 jint GetNativeInstanceCount(JNIEnv* env, jclass) {
360 return base::subtle::NoBarrier_Load(&g_instance_count);
363 jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) {
364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
365 return reinterpret_cast<jint>(&browser_view_renderer_);
368 namespace {
369 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message,
370 bool has_images) {
371 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(),
372 has_images,
373 message.obj());
375 } // namespace
377 void AwContents::DocumentHasImages(JNIEnv* env, jobject obj, jobject message) {
378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
379 ScopedJavaGlobalRef<jobject> j_message;
380 j_message.Reset(env, message);
381 render_view_host_ext_->DocumentHasImages(
382 base::Bind(&DocumentHasImagesCallback, j_message));
385 namespace {
386 void GenerateMHTMLCallback(ScopedJavaGlobalRef<jobject>* callback,
387 const base::FilePath& path, int64 size) {
388 JNIEnv* env = AttachCurrentThread();
389 // Android files are UTF8, so the path conversion below is safe.
390 Java_AwContents_generateMHTMLCallback(
391 env,
392 ConvertUTF8ToJavaString(env, path.AsUTF8Unsafe()).obj(),
393 size, callback->obj());
395 } // namespace
397 void AwContents::GenerateMHTML(JNIEnv* env, jobject obj,
398 jstring jpath, jobject callback) {
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
400 ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
401 j_callback->Reset(env, callback);
402 base::FilePath target_path(ConvertJavaStringToUTF8(env, jpath));
403 web_contents_->GenerateMHTML(
404 target_path,
405 base::Bind(&GenerateMHTMLCallback, base::Owned(j_callback), target_path));
408 void AwContents::CreatePdfExporter(JNIEnv* env,
409 jobject obj,
410 jobject pdfExporter) {
411 pdf_exporter_.reset(
412 new AwPdfExporter(env,
413 pdfExporter,
414 web_contents_.get()));
417 bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler,
418 const std::string& host,
419 const std::string& realm) {
420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
421 JNIEnv* env = AttachCurrentThread();
422 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
423 if (obj.is_null())
424 return false;
426 ScopedJavaLocalRef<jstring> jhost = ConvertUTF8ToJavaString(env, host);
427 ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm);
428 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
429 "onReceivedHttpAuthRequest");
430 Java_AwContents_onReceivedHttpAuthRequest(env, obj.obj(), handler.obj(),
431 jhost.obj(), jrealm.obj());
432 return true;
435 void AwContents::AddVisitedLinks(JNIEnv* env,
436 jobject obj,
437 jobjectArray jvisited_links) {
438 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
439 std::vector<base::string16> visited_link_strings;
440 base::android::AppendJavaStringArrayToStringVector(
441 env, jvisited_links, &visited_link_strings);
443 std::vector<GURL> visited_link_gurls;
444 std::vector<base::string16>::const_iterator itr;
445 for (itr = visited_link_strings.begin(); itr != visited_link_strings.end();
446 ++itr) {
447 visited_link_gurls.push_back(GURL(*itr));
450 AwBrowserContext::FromWebContents(web_contents_.get())
451 ->AddVisitedURLs(visited_link_gurls);
454 bool RegisterAwContents(JNIEnv* env) {
455 return RegisterNativesImpl(env) >= 0;
458 namespace {
460 void ShowGeolocationPromptHelperTask(const JavaObjectWeakGlobalRef& java_ref,
461 const GURL& origin) {
462 JNIEnv* env = AttachCurrentThread();
463 ScopedJavaLocalRef<jobject> j_ref = java_ref.get(env);
464 if (j_ref.obj()) {
465 ScopedJavaLocalRef<jstring> j_origin(
466 ConvertUTF8ToJavaString(env, origin.spec()));
467 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
468 "onGeolocationPermissionsShowPrompt");
469 Java_AwContents_onGeolocationPermissionsShowPrompt(env,
470 j_ref.obj(),
471 j_origin.obj());
475 void ShowGeolocationPromptHelper(const JavaObjectWeakGlobalRef& java_ref,
476 const GURL& origin) {
477 JNIEnv* env = AttachCurrentThread();
478 if (java_ref.get(env).obj()) {
479 content::BrowserThread::PostTask(
480 content::BrowserThread::UI,
481 FROM_HERE,
482 base::Bind(&ShowGeolocationPromptHelperTask,
483 java_ref,
484 origin));
488 } // anonymous namespace
490 void AwContents::ShowGeolocationPrompt(const GURL& requesting_frame,
491 base::Callback<void(bool)> callback) {
492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
494 GURL origin = requesting_frame.GetOrigin();
495 bool show_prompt = pending_geolocation_prompts_.empty();
496 pending_geolocation_prompts_.push_back(OriginCallback(origin, callback));
497 if (show_prompt) {
498 ShowGeolocationPromptHelper(java_ref_, origin);
502 // Invoked from Java
503 void AwContents::InvokeGeolocationCallback(JNIEnv* env,
504 jobject obj,
505 jboolean value,
506 jstring origin) {
507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
509 GURL callback_origin(base::android::ConvertJavaStringToUTF16(env, origin));
510 if (callback_origin.GetOrigin() ==
511 pending_geolocation_prompts_.front().first) {
512 pending_geolocation_prompts_.front().second.Run(value);
513 pending_geolocation_prompts_.pop_front();
514 if (!pending_geolocation_prompts_.empty()) {
515 ShowGeolocationPromptHelper(java_ref_,
516 pending_geolocation_prompts_.front().first);
521 void AwContents::HideGeolocationPrompt(const GURL& origin) {
522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
523 bool removed_current_outstanding_callback = false;
524 std::list<OriginCallback>::iterator it = pending_geolocation_prompts_.begin();
525 while (it != pending_geolocation_prompts_.end()) {
526 if ((*it).first == origin.GetOrigin()) {
527 if (it == pending_geolocation_prompts_.begin()) {
528 removed_current_outstanding_callback = true;
530 it = pending_geolocation_prompts_.erase(it);
531 } else {
532 ++it;
536 if (removed_current_outstanding_callback) {
537 JNIEnv* env = AttachCurrentThread();
538 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
539 if (j_ref.obj()) {
540 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
541 "onGeolocationPermissionsHidePrompt");
542 Java_AwContents_onGeolocationPermissionsHidePrompt(env, j_ref.obj());
544 if (!pending_geolocation_prompts_.empty()) {
545 ShowGeolocationPromptHelper(java_ref_,
546 pending_geolocation_prompts_.front().first);
551 void AwContents::FindAllAsync(JNIEnv* env, jobject obj, jstring search_string) {
552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
553 GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string));
556 void AwContents::FindNext(JNIEnv* env, jobject obj, jboolean forward) {
557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
558 GetFindHelper()->FindNext(forward);
561 void AwContents::ClearMatches(JNIEnv* env, jobject obj) {
562 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
563 GetFindHelper()->ClearMatches();
566 void AwContents::ClearCache(
567 JNIEnv* env,
568 jobject obj,
569 jboolean include_disk_files) {
570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
571 render_view_host_ext_->ClearCache();
573 if (include_disk_files) {
574 RemoveHttpDiskCache(web_contents_->GetBrowserContext(),
575 web_contents_->GetRoutingID());
579 FindHelper* AwContents::GetFindHelper() {
580 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
581 if (!find_helper_.get()) {
582 find_helper_.reset(new FindHelper(web_contents_.get()));
583 find_helper_->SetListener(this);
585 return find_helper_.get();
588 void AwContents::OnFindResultReceived(int active_ordinal,
589 int match_count,
590 bool finished) {
591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
592 JNIEnv* env = AttachCurrentThread();
593 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
594 if (obj.is_null())
595 return;
597 Java_AwContents_onFindResultReceived(
598 env, obj.obj(), active_ordinal, match_count, finished);
601 bool AwContents::ShouldDownloadFavicon(const GURL& icon_url) {
602 return g_should_download_favicons;
605 void AwContents::OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) {
606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
607 JNIEnv* env = AttachCurrentThread();
608 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
609 if (obj.is_null())
610 return;
612 content::NavigationEntry* entry =
613 web_contents_->GetController().GetActiveEntry();
615 if (entry) {
616 entry->GetFavicon().valid = true;
617 entry->GetFavicon().url = icon_url;
618 entry->GetFavicon().image = gfx::Image::CreateFrom1xBitmap(bitmap);
621 Java_AwContents_onReceivedIcon(
622 env, obj.obj(), gfx::ConvertToJavaBitmap(&bitmap).obj());
625 void AwContents::OnReceivedTouchIconUrl(const std::string& url,
626 bool precomposed) {
627 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
628 JNIEnv* env = AttachCurrentThread();
629 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
630 if (obj.is_null())
631 return;
633 Java_AwContents_onReceivedTouchIconUrl(
634 env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed);
637 bool AwContents::RequestDrawGL(jobject canvas) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
639 JNIEnv* env = AttachCurrentThread();
640 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
641 if (obj.is_null())
642 return false;
643 return Java_AwContents_requestDrawGL(env, obj.obj(), canvas);
646 void AwContents::PostInvalidate() {
647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
648 JNIEnv* env = AttachCurrentThread();
649 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
650 if (!obj.is_null())
651 Java_AwContents_postInvalidateOnAnimation(env, obj.obj());
654 void AwContents::UpdateGlobalVisibleRect() {
655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
656 JNIEnv* env = AttachCurrentThread();
657 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
658 if (!obj.is_null())
659 Java_AwContents_updateGlobalVisibleRect(env, obj.obj());
662 void AwContents::OnNewPicture() {
663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
664 JNIEnv* env = AttachCurrentThread();
665 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
666 if (!obj.is_null()) {
667 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
668 "onNewPicture");
669 Java_AwContents_onNewPicture(env, obj.obj());
673 base::android::ScopedJavaLocalRef<jbyteArray>
674 AwContents::GetCertificate(JNIEnv* env,
675 jobject obj) {
676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
677 content::NavigationEntry* entry =
678 web_contents_->GetController().GetActiveEntry();
679 if (!entry)
680 return ScopedJavaLocalRef<jbyteArray>();
681 // Get the certificate
682 int cert_id = entry->GetSSL().cert_id;
683 scoped_refptr<net::X509Certificate> cert;
684 bool ok = content::CertStore::GetInstance()->RetrieveCert(cert_id, &cert);
685 if (!ok)
686 return ScopedJavaLocalRef<jbyteArray>();
688 // Convert the certificate and return it
689 std::string der_string;
690 net::X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_string);
691 return base::android::ToJavaByteArray(env,
692 reinterpret_cast<const uint8*>(der_string.data()), der_string.length());
695 void AwContents::RequestNewHitTestDataAt(JNIEnv* env, jobject obj,
696 jint x, jint y) {
697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
698 render_view_host_ext_->RequestNewHitTestDataAt(x, y);
701 void AwContents::UpdateLastHitTestData(JNIEnv* env, jobject obj) {
702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
703 if (!render_view_host_ext_->HasNewHitTestData()) return;
705 const AwHitTestData& data = render_view_host_ext_->GetLastHitTestData();
706 render_view_host_ext_->MarkHitTestDataRead();
708 // Make sure to null the Java object if data is empty/invalid.
709 ScopedJavaLocalRef<jstring> extra_data_for_type;
710 if (data.extra_data_for_type.length())
711 extra_data_for_type = ConvertUTF8ToJavaString(
712 env, data.extra_data_for_type);
714 ScopedJavaLocalRef<jstring> href;
715 if (data.href.length())
716 href = ConvertUTF16ToJavaString(env, data.href);
718 ScopedJavaLocalRef<jstring> anchor_text;
719 if (data.anchor_text.length())
720 anchor_text = ConvertUTF16ToJavaString(env, data.anchor_text);
722 ScopedJavaLocalRef<jstring> img_src;
723 if (data.img_src.is_valid())
724 img_src = ConvertUTF8ToJavaString(env, data.img_src.spec());
726 Java_AwContents_updateHitTestData(env,
727 obj,
728 data.type,
729 extra_data_for_type.obj(),
730 href.obj(),
731 anchor_text.obj(),
732 img_src.obj());
735 void AwContents::OnSizeChanged(JNIEnv* env, jobject obj,
736 int w, int h, int ow, int oh) {
737 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
738 browser_view_renderer_.OnSizeChanged(w, h);
741 void AwContents::SetViewVisibility(JNIEnv* env, jobject obj, bool visible) {
742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
743 browser_view_renderer_.SetViewVisibility(visible);
746 void AwContents::SetWindowVisibility(JNIEnv* env, jobject obj, bool visible) {
747 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
748 browser_view_renderer_.SetWindowVisibility(visible);
751 void AwContents::SetIsPaused(JNIEnv* env, jobject obj, bool paused) {
752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
753 browser_view_renderer_.SetIsPaused(paused);
754 ContentViewCore* cvc =
755 ContentViewCore::FromWebContents(web_contents_.get());
756 if (cvc) {
757 cvc->PauseOrResumeGeolocation(paused);
758 if (paused) {
759 cvc->PauseVideo();
764 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) {
765 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
766 browser_view_renderer_.OnAttachedToWindow(w, h);
769 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
770 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
771 browser_view_renderer_.OnDetachedFromWindow();
774 base::android::ScopedJavaLocalRef<jbyteArray>
775 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) {
776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
777 // Required optimization in WebViewClassic to not save any state if
778 // there has been no navigations.
779 if (!web_contents_->GetController().GetEntryCount())
780 return ScopedJavaLocalRef<jbyteArray>();
782 Pickle pickle;
783 if (!WriteToPickle(*web_contents_, &pickle)) {
784 return ScopedJavaLocalRef<jbyteArray>();
785 } else {
786 return base::android::ToJavaByteArray(env,
787 reinterpret_cast<const uint8*>(pickle.data()), pickle.size());
791 jboolean AwContents::RestoreFromOpaqueState(
792 JNIEnv* env, jobject obj, jbyteArray state) {
793 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
794 // TODO(boliu): This copy can be optimized out if this is a performance
795 // problem.
796 std::vector<uint8> state_vector;
797 base::android::JavaByteArrayToByteVector(env, state, &state_vector);
799 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()),
800 state_vector.size());
801 PickleIterator iterator(pickle);
803 return RestoreFromPickle(&iterator, web_contents_.get());
806 bool AwContents::OnDraw(JNIEnv* env,
807 jobject obj,
808 jobject canvas,
809 jboolean is_hardware_accelerated,
810 jint scroll_x,
811 jint scroll_y,
812 jint clip_left,
813 jint clip_top,
814 jint clip_right,
815 jint clip_bottom) {
816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
817 return browser_view_renderer_.OnDraw(
818 canvas,
819 is_hardware_accelerated,
820 gfx::Vector2d(scroll_x, scroll_y),
821 gfx::Rect(
822 clip_left, clip_top, clip_right - clip_left, clip_bottom - clip_top));
825 void AwContents::SetGlobalVisibleRect(JNIEnv* env,
826 jobject obj,
827 jint visible_left,
828 jint visible_top,
829 jint visible_right,
830 jint visible_bottom) {
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
832 browser_view_renderer_.SetGlobalVisibleRect(
833 gfx::Rect(visible_left,
834 visible_top,
835 visible_right - visible_left,
836 visible_bottom - visible_top));
839 void AwContents::SetPendingWebContentsForPopup(
840 scoped_ptr<content::WebContents> pending) {
841 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
842 if (pending_contents_.get()) {
843 // TODO(benm): Support holding multiple pop up window requests.
844 LOG(WARNING) << "Blocking popup window creation as an outstanding "
845 << "popup window is still pending.";
846 base::MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release());
847 return;
849 pending_contents_.reset(new AwContents(pending.Pass()));
852 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) {
853 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
854 web_contents_->FocusThroughTabTraversal(false);
857 void AwContents::SetBackgroundColor(JNIEnv* env, jobject obj, jint color) {
858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
859 render_view_host_ext_->SetBackgroundColor(color);
862 jint AwContents::ReleasePopupAwContents(JNIEnv* env, jobject obj) {
863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
864 return reinterpret_cast<jint>(pending_contents_.release());
867 gfx::Point AwContents::GetLocationOnScreen() {
868 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
869 JNIEnv* env = AttachCurrentThread();
870 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
871 if (obj.is_null())
872 return gfx::Point();
873 std::vector<int> location;
874 base::android::JavaIntArrayToIntVector(
875 env,
876 Java_AwContents_getLocationOnScreen(env, obj.obj()).obj(),
877 &location);
878 return gfx::Point(location[0], location[1]);
881 void AwContents::SetMaxContainerViewScrollOffset(gfx::Vector2d new_value) {
882 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
883 JNIEnv* env = AttachCurrentThread();
884 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
885 if (obj.is_null())
886 return;
887 Java_AwContents_setMaxContainerViewScrollOffset(
888 env, obj.obj(), new_value.x(), new_value.y());
891 void AwContents::ScrollContainerViewTo(gfx::Vector2d new_value) {
892 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
893 JNIEnv* env = AttachCurrentThread();
894 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
895 if (obj.is_null())
896 return;
897 Java_AwContents_scrollContainerViewTo(
898 env, obj.obj(), new_value.x(), new_value.y());
901 bool AwContents::IsFlingActive() const {
902 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
903 JNIEnv* env = AttachCurrentThread();
904 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
905 if (obj.is_null())
906 return false;
907 return Java_AwContents_isFlingActive(env, obj.obj());
910 void AwContents::SetPageScaleFactorAndLimits(
911 float page_scale_factor,
912 float min_page_scale_factor,
913 float max_page_scale_factor) {
914 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
915 JNIEnv* env = AttachCurrentThread();
916 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
917 if (obj.is_null())
918 return;
919 Java_AwContents_setPageScaleFactorAndLimits(env,
920 obj.obj(),
921 page_scale_factor,
922 min_page_scale_factor,
923 max_page_scale_factor);
926 void AwContents::SetContentsSize(gfx::SizeF contents_size_dip) {
927 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
928 JNIEnv* env = AttachCurrentThread();
929 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
930 if (obj.is_null())
931 return;
932 Java_AwContents_setContentsSize(
933 env, obj.obj(), contents_size_dip.width(), contents_size_dip.height());
936 void AwContents::DidOverscroll(gfx::Vector2d overscroll_delta) {
937 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
938 JNIEnv* env = AttachCurrentThread();
939 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
940 if (obj.is_null())
941 return;
942 Java_AwContents_didOverscroll(
943 env, obj.obj(), overscroll_delta.x(), overscroll_delta.y());
946 const BrowserViewRenderer* AwContents::GetBrowserViewRenderer() const {
947 return &browser_view_renderer_;
950 void AwContents::SetDipScale(JNIEnv* env, jobject obj, jfloat dip_scale) {
951 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
952 browser_view_renderer_.SetDipScale(dip_scale);
955 void AwContents::SetFixedLayoutSize(JNIEnv* env,
956 jobject obj,
957 jint width_dip,
958 jint height_dip) {
959 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
960 render_view_host_ext_->SetFixedLayoutSize(gfx::Size(width_dip, height_dip));
963 void AwContents::ScrollTo(JNIEnv* env, jobject obj, jint x, jint y) {
964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
965 browser_view_renderer_.ScrollTo(gfx::Vector2d(x, y));
968 void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) {
969 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
970 JNIEnv* env = AttachCurrentThread();
971 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
972 if (obj.is_null())
973 return;
974 Java_AwContents_onWebLayoutPageScaleFactorChanged(env, obj.obj(),
975 page_scale_factor);
978 void AwContents::OnWebLayoutContentsSizeChanged(
979 const gfx::Size& contents_size) {
980 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
981 JNIEnv* env = AttachCurrentThread();
982 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
983 if (obj.is_null())
984 return;
985 Java_AwContents_onWebLayoutContentsSizeChanged(
986 env, obj.obj(), contents_size.width(), contents_size.height());
989 jlong AwContents::CapturePicture(JNIEnv* env,
990 jobject obj,
991 int width,
992 int height) {
993 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
994 return reinterpret_cast<intptr_t>(
995 new AwPicture(browser_view_renderer_.CapturePicture(width, height)));
998 void AwContents::EnableOnNewPicture(JNIEnv* env,
999 jobject obj,
1000 jboolean enabled) {
1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1002 browser_view_renderer_.EnableOnNewPicture(enabled);
1005 void AwContents::ClearView(JNIEnv* env, jobject obj) {
1006 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1007 browser_view_renderer_.ClearView();
1010 void AwContents::SetExtraHeadersForUrl(JNIEnv* env, jobject obj,
1011 jstring url, jstring jextra_headers) {
1012 std::string extra_headers;
1013 if (jextra_headers)
1014 extra_headers = ConvertJavaStringToUTF8(env, jextra_headers);
1015 AwResourceContext* resource_context = static_cast<AwResourceContext*>(
1016 AwBrowserContext::FromWebContents(web_contents_.get())->
1017 GetResourceContext());
1018 resource_context->SetExtraHeaders(GURL(ConvertJavaStringToUTF8(env, url)),
1019 extra_headers);
1022 void AwContents::SetJsOnlineProperty(JNIEnv* env,
1023 jobject obj,
1024 jboolean network_up) {
1025 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1026 render_view_host_ext_->SetJsOnlineProperty(network_up);
1029 void AwContents::TrimMemory(JNIEnv* env, jobject obj, jint level) {
1030 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1031 browser_view_renderer_.TrimMemory(level);
1034 void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) {
1035 g_should_download_favicons = true;
1038 } // namespace android_webview