[Android WebView] Handle clip size smaller than visible rect
[chromium-blink-merge.git] / android_webview / native / aw_contents.cc
blob4ef093e20c42b8699f0a2aaf324c472365f1a830
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 "android_webview/browser/aw_browser_context.h"
8 #include "android_webview/browser/aw_browser_main_parts.h"
9 #include "android_webview/browser/gpu_memory_buffer_factory_impl.h"
10 #include "android_webview/browser/in_process_view_renderer.h"
11 #include "android_webview/browser/net_disk_cache_remover.h"
12 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
13 #include "android_webview/common/aw_hit_test_data.h"
14 #include "android_webview/native/aw_autofill_manager_delegate.h"
15 #include "android_webview/native/aw_browser_dependency_factory.h"
16 #include "android_webview/native/aw_contents_client_bridge.h"
17 #include "android_webview/native/aw_contents_io_thread_client_impl.h"
18 #include "android_webview/native/aw_web_contents_delegate.h"
19 #include "android_webview/native/java_browser_view_renderer_helper.h"
20 #include "android_webview/native/state_serializer.h"
21 #include "android_webview/public/browser/draw_gl.h"
22 #include "base/android/jni_android.h"
23 #include "base/android/jni_array.h"
24 #include "base/android/jni_string.h"
25 #include "base/android/scoped_java_ref.h"
26 #include "base/atomicops.h"
27 #include "base/bind.h"
28 #include "base/callback.h"
29 #include "base/message_loop/message_loop.h"
30 #include "base/pickle.h"
31 #include "base/strings/string16.h"
32 #include "base/supports_user_data.h"
33 #include "components/autofill/content/browser/autofill_driver_impl.h"
34 #include "components/autofill/core/browser/autofill_manager.h"
35 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
36 #include "components/navigation_interception/intercept_navigation_delegate.h"
37 #include "content/public/browser/android/content_view_core.h"
38 #include "content/public/browser/browser_thread.h"
39 #include "content/public/browser/cert_store.h"
40 #include "content/public/browser/favicon_status.h"
41 #include "content/public/browser/navigation_entry.h"
42 #include "content/public/browser/render_process_host.h"
43 #include "content/public/browser/render_view_host.h"
44 #include "content/public/browser/web_contents.h"
45 #include "content/public/common/ssl_status.h"
46 #include "jni/AwContents_jni.h"
47 #include "net/cert/x509_certificate.h"
48 #include "ui/base/l10n/l10n_util_android.h"
49 #include "ui/gfx/android/java_bitmap.h"
50 #include "ui/gfx/image/image.h"
52 struct AwDrawSWFunctionTable;
53 struct AwDrawGLFunctionTable;
55 using autofill::AutofillDriverImpl;
56 using autofill::AutofillManager;
57 using base::android::AttachCurrentThread;
58 using base::android::ConvertJavaStringToUTF16;
59 using base::android::ConvertJavaStringToUTF8;
60 using base::android::ConvertUTF16ToJavaString;
61 using base::android::ConvertUTF8ToJavaString;
62 using base::android::JavaRef;
63 using base::android::ScopedJavaGlobalRef;
64 using base::android::ScopedJavaLocalRef;
65 using navigation_interception::InterceptNavigationDelegate;
66 using content::BrowserThread;
67 using content::ContentViewCore;
68 using content::WebContents;
70 extern "C" {
71 static AwDrawGLFunction DrawGLFunction;
72 static void DrawGLFunction(int view_context,
73 AwDrawGLInfo* draw_info,
74 void* spare) {
75 // |view_context| is the value that was returned from the java
76 // AwContents.onPrepareDrawGL; this cast must match the code there.
77 reinterpret_cast<android_webview::BrowserViewRenderer*>(view_context)->DrawGL(
78 draw_info);
82 namespace android_webview {
84 namespace {
86 JavaBrowserViewRendererHelper* java_renderer_helper() {
87 static JavaBrowserViewRendererHelper* g_instance
88 = new JavaBrowserViewRendererHelper;
89 return g_instance;
92 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey;
94 class AwContentsUserData : public base::SupportsUserData::Data {
95 public:
96 AwContentsUserData(AwContents* ptr) : contents_(ptr) {}
98 static AwContents* GetContents(WebContents* web_contents) {
99 if (!web_contents)
100 return NULL;
101 AwContentsUserData* data = reinterpret_cast<AwContentsUserData*>(
102 web_contents->GetUserData(kAwContentsUserDataKey));
103 return data ? data->contents_ : NULL;
106 private:
107 AwContents* contents_;
110 base::subtle::Atomic32 g_instance_count = 0;
112 } // namespace
114 // static
115 AwContents* AwContents::FromWebContents(WebContents* web_contents) {
116 return AwContentsUserData::GetContents(web_contents);
119 // static
120 AwContents* AwContents::FromID(int render_process_id, int render_view_id) {
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122 const content::RenderViewHost* rvh =
123 content::RenderViewHost::FromID(render_process_id, render_view_id);
124 if (!rvh) return NULL;
125 content::WebContents* web_contents =
126 content::WebContents::FromRenderViewHost(rvh);
127 if (!web_contents) return NULL;
128 return FromWebContents(web_contents);
131 AwContents::AwContents(scoped_ptr<WebContents> web_contents)
132 : web_contents_(web_contents.Pass()),
133 browser_view_renderer_(
134 new InProcessViewRenderer(this, java_renderer_helper(),
135 web_contents_.get())) {
136 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
137 icon_helper_.reset(new IconHelper(web_contents_.get()));
138 icon_helper_->SetListener(this);
139 web_contents_->SetUserData(kAwContentsUserDataKey,
140 new AwContentsUserData(this));
141 render_view_host_ext_.reset(
142 new AwRenderViewHostExt(this, web_contents_.get()));
144 AwAutofillManagerDelegate* autofill_manager_delegate =
145 AwAutofillManagerDelegate::FromWebContents(web_contents_.get());
146 if (autofill_manager_delegate)
147 InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
150 void AwContents::SetJavaPeers(JNIEnv* env,
151 jobject obj,
152 jobject aw_contents,
153 jobject web_contents_delegate,
154 jobject contents_client_bridge,
155 jobject io_thread_client,
156 jobject intercept_navigation_delegate) {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 // The |aw_content| param is technically spurious as it duplicates |obj| but
159 // is passed over anyway to make the binding more explicit.
160 java_ref_ = JavaObjectWeakGlobalRef(env, aw_contents);
162 web_contents_delegate_.reset(
163 new AwWebContentsDelegate(env, web_contents_delegate));
164 web_contents_->SetDelegate(web_contents_delegate_.get());
166 contents_client_bridge_.reset(
167 new AwContentsClientBridge(env, contents_client_bridge));
168 AwContentsClientBridgeBase::Associate(web_contents_.get(),
169 contents_client_bridge_.get());
171 AwContentsIoThreadClientImpl::Associate(
172 web_contents_.get(), ScopedJavaLocalRef<jobject>(env, io_thread_client));
173 int child_id = web_contents_->GetRenderProcessHost()->GetID();
174 int route_id = web_contents_->GetRoutingID();
175 AwResourceDispatcherHostDelegate::OnIoThreadClientReady(child_id, route_id);
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
178 InterceptNavigationDelegate::Associate(
179 web_contents_.get(),
180 make_scoped_ptr(new InterceptNavigationDelegate(
181 env, intercept_navigation_delegate)));
184 void AwContents::SetSaveFormData(bool enabled) {
185 InitAutofillIfNecessary(enabled);
186 // We need to check for the existence, since autofill_manager_delegate
187 // may not be created when the setting is false.
188 if (AutofillDriverImpl::FromWebContents(web_contents_.get())) {
189 AwAutofillManagerDelegate::FromWebContents(web_contents_.get())->
190 SetSaveFormData(enabled);
194 void AwContents::InitAutofillIfNecessary(bool enabled) {
195 // Do not initialize if the feature is not enabled.
196 if (!enabled)
197 return;
198 // Check if the autofill driver already exists.
199 content::WebContents* web_contents = web_contents_.get();
200 if (AutofillDriverImpl::FromWebContents(web_contents))
201 return;
203 AwBrowserContext::FromWebContents(web_contents)->
204 CreateUserPrefServiceIfNecessary();
205 AwAutofillManagerDelegate::CreateForWebContents(web_contents);
206 AutofillDriverImpl::CreateForWebContentsAndDelegate(
207 web_contents,
208 AwAutofillManagerDelegate::FromWebContents(web_contents),
209 l10n_util::GetDefaultLocale(),
210 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
213 void AwContents::SetAwAutofillManagerDelegate(jobject delegate) {
214 JNIEnv* env = AttachCurrentThread();
215 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
216 if (obj.is_null())
217 return;
218 Java_AwContents_setAwAutofillManagerDelegate(env, obj.obj(), delegate);
221 AwContents::~AwContents() {
222 DCHECK(AwContents::FromWebContents(web_contents_.get()) == this);
223 web_contents_->RemoveUserData(kAwContentsUserDataKey);
224 if (find_helper_.get())
225 find_helper_->SetListener(NULL);
226 if (icon_helper_.get())
227 icon_helper_->SetListener(NULL);
228 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1);
231 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) {
232 DCHECK(web_contents_);
233 return reinterpret_cast<jint>(web_contents_.get());
236 void AwContents::Destroy(JNIEnv* env, jobject obj) {
237 delete this;
240 static jint Init(JNIEnv* env, jclass, jobject browser_context) {
241 // TODO(joth): Use |browser_context| to get the native BrowserContext, rather
242 // than hard-code the default instance lookup here.
243 scoped_ptr<WebContents> web_contents(content::WebContents::Create(
244 content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
245 // Return an 'uninitialized' instance; most work is deferred until the
246 // subsequent SetJavaPeers() call.
247 return reinterpret_cast<jint>(new AwContents(web_contents.Pass()));
250 static void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) {
251 BrowserViewRenderer::SetAwDrawSWFunctionTable(
252 reinterpret_cast<AwDrawSWFunctionTable*>(function_table));
255 static void SetAwDrawGLFunctionTable(JNIEnv* env, jclass, jint function_table) {
256 GpuMemoryBufferFactoryImpl::SetAwDrawGLFunctionTable(
257 reinterpret_cast<AwDrawGLFunctionTable*>(function_table));
260 static jint GetAwDrawGLFunction(JNIEnv* env, jclass) {
261 return reinterpret_cast<jint>(&DrawGLFunction);
264 // static
265 jint GetNativeInstanceCount(JNIEnv* env, jclass) {
266 return base::subtle::NoBarrier_Load(&g_instance_count);
269 jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) {
270 return reinterpret_cast<jint>(browser_view_renderer_.get());
273 namespace {
274 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message,
275 bool has_images) {
276 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(),
277 has_images,
278 message.obj());
280 } // namespace
282 void AwContents::DocumentHasImages(JNIEnv* env, jobject obj, jobject message) {
283 ScopedJavaGlobalRef<jobject> j_message;
284 j_message.Reset(env, message);
285 render_view_host_ext_->DocumentHasImages(
286 base::Bind(&DocumentHasImagesCallback, j_message));
289 namespace {
290 void GenerateMHTMLCallback(ScopedJavaGlobalRef<jobject>* callback,
291 const base::FilePath& path, int64 size) {
292 JNIEnv* env = AttachCurrentThread();
293 // Android files are UTF8, so the path conversion below is safe.
294 Java_AwContents_generateMHTMLCallback(
295 env,
296 ConvertUTF8ToJavaString(env, path.AsUTF8Unsafe()).obj(),
297 size, callback->obj());
299 } // namespace
301 void AwContents::GenerateMHTML(JNIEnv* env, jobject obj,
302 jstring jpath, jobject callback) {
303 ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
304 j_callback->Reset(env, callback);
305 web_contents_->GenerateMHTML(
306 base::FilePath(ConvertJavaStringToUTF8(env, jpath)),
307 base::Bind(&GenerateMHTMLCallback, base::Owned(j_callback)));
310 void AwContents::PerformLongClick() {
311 JNIEnv* env = AttachCurrentThread();
312 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
313 if (obj.is_null())
314 return;
316 Java_AwContents_performLongClick(env, obj.obj());
319 bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler,
320 const std::string& host,
321 const std::string& realm) {
322 JNIEnv* env = AttachCurrentThread();
323 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
324 if (obj.is_null())
325 return false;
327 ScopedJavaLocalRef<jstring> jhost = ConvertUTF8ToJavaString(env, host);
328 ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm);
329 Java_AwContents_onReceivedHttpAuthRequest(env, obj.obj(), handler.obj(),
330 jhost.obj(), jrealm.obj());
331 return true;
334 void AwContents::AddVisitedLinks(JNIEnv* env,
335 jobject obj,
336 jobjectArray jvisited_links) {
337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
338 std::vector<string16> visited_link_strings;
339 base::android::AppendJavaStringArrayToStringVector(
340 env, jvisited_links, &visited_link_strings);
342 std::vector<GURL> visited_link_gurls;
343 for (std::vector<string16>::const_iterator itr = visited_link_strings.begin();
344 itr != visited_link_strings.end();
345 ++itr) {
346 visited_link_gurls.push_back(GURL(*itr));
349 AwBrowserContext::FromWebContents(web_contents_.get())
350 ->AddVisitedURLs(visited_link_gurls);
353 bool RegisterAwContents(JNIEnv* env) {
354 return RegisterNativesImpl(env) >= 0;
357 namespace {
359 void ShowGeolocationPromptHelperTask(const JavaObjectWeakGlobalRef& java_ref,
360 const GURL& origin) {
361 JNIEnv* env = AttachCurrentThread();
362 ScopedJavaLocalRef<jobject> j_ref = java_ref.get(env);
363 if (j_ref.obj()) {
364 ScopedJavaLocalRef<jstring> j_origin(
365 ConvertUTF8ToJavaString(env, origin.spec()));
366 Java_AwContents_onGeolocationPermissionsShowPrompt(env,
367 j_ref.obj(),
368 j_origin.obj());
372 void ShowGeolocationPromptHelper(const JavaObjectWeakGlobalRef& java_ref,
373 const GURL& origin) {
374 JNIEnv* env = AttachCurrentThread();
375 if (java_ref.get(env).obj()) {
376 content::BrowserThread::PostTask(
377 content::BrowserThread::UI,
378 FROM_HERE,
379 base::Bind(&ShowGeolocationPromptHelperTask,
380 java_ref,
381 origin));
385 } // anonymous namespace
387 void AwContents::ShowGeolocationPrompt(const GURL& requesting_frame,
388 base::Callback<void(bool)> callback) {
389 GURL origin = requesting_frame.GetOrigin();
390 bool show_prompt = pending_geolocation_prompts_.empty();
391 pending_geolocation_prompts_.push_back(OriginCallback(origin, callback));
392 if (show_prompt) {
393 ShowGeolocationPromptHelper(java_ref_, origin);
397 // Invoked from Java
398 void AwContents::InvokeGeolocationCallback(JNIEnv* env,
399 jobject obj,
400 jboolean value,
401 jstring origin) {
402 GURL callback_origin(base::android::ConvertJavaStringToUTF16(env, origin));
403 if (callback_origin.GetOrigin() ==
404 pending_geolocation_prompts_.front().first) {
405 pending_geolocation_prompts_.front().second.Run(value);
406 pending_geolocation_prompts_.pop_front();
407 if (!pending_geolocation_prompts_.empty()) {
408 ShowGeolocationPromptHelper(java_ref_,
409 pending_geolocation_prompts_.front().first);
414 void AwContents::HideGeolocationPrompt(const GURL& origin) {
415 bool removed_current_outstanding_callback = false;
416 std::list<OriginCallback>::iterator it = pending_geolocation_prompts_.begin();
417 while (it != pending_geolocation_prompts_.end()) {
418 if ((*it).first == origin.GetOrigin()) {
419 if (it == pending_geolocation_prompts_.begin()) {
420 removed_current_outstanding_callback = true;
422 it = pending_geolocation_prompts_.erase(it);
423 } else {
424 ++it;
428 if (removed_current_outstanding_callback) {
429 JNIEnv* env = AttachCurrentThread();
430 ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
431 if (j_ref.obj()) {
432 Java_AwContents_onGeolocationPermissionsHidePrompt(env, j_ref.obj());
434 if (!pending_geolocation_prompts_.empty()) {
435 ShowGeolocationPromptHelper(java_ref_,
436 pending_geolocation_prompts_.front().first);
441 void AwContents::FindAllAsync(JNIEnv* env, jobject obj, jstring search_string) {
442 GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string));
445 void AwContents::FindNext(JNIEnv* env, jobject obj, jboolean forward) {
446 GetFindHelper()->FindNext(forward);
449 void AwContents::ClearMatches(JNIEnv* env, jobject obj) {
450 GetFindHelper()->ClearMatches();
453 void AwContents::ClearCache(
454 JNIEnv* env,
455 jobject obj,
456 jboolean include_disk_files) {
457 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
458 render_view_host_ext_->ClearCache();
460 if (include_disk_files) {
461 RemoveHttpDiskCache(web_contents_->GetBrowserContext(),
462 web_contents_->GetRoutingID());
466 FindHelper* AwContents::GetFindHelper() {
467 if (!find_helper_.get()) {
468 find_helper_.reset(new FindHelper(web_contents_.get()));
469 find_helper_->SetListener(this);
471 return find_helper_.get();
474 void AwContents::OnFindResultReceived(int active_ordinal,
475 int match_count,
476 bool finished) {
477 JNIEnv* env = AttachCurrentThread();
478 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
479 if (obj.is_null())
480 return;
482 Java_AwContents_onFindResultReceived(
483 env, obj.obj(), active_ordinal, match_count, finished);
486 void AwContents::OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) {
487 JNIEnv* env = AttachCurrentThread();
488 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
489 if (obj.is_null())
490 return;
492 content::NavigationEntry* entry =
493 web_contents_->GetController().GetActiveEntry();
495 if (entry) {
496 entry->GetFavicon().valid = true;
497 entry->GetFavicon().url = icon_url;
498 entry->GetFavicon().image = gfx::Image::CreateFrom1xBitmap(bitmap);
501 Java_AwContents_onReceivedIcon(
502 env, obj.obj(), gfx::ConvertToJavaBitmap(&bitmap).obj());
505 void AwContents::OnReceivedTouchIconUrl(const std::string& url,
506 bool precomposed) {
507 JNIEnv* env = AttachCurrentThread();
508 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
509 if (obj.is_null())
510 return;
512 Java_AwContents_onReceivedTouchIconUrl(
513 env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed);
516 bool AwContents::RequestDrawGL(jobject canvas) {
517 JNIEnv* env = AttachCurrentThread();
518 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
519 if (obj.is_null())
520 return false;
521 return Java_AwContents_requestDrawGL(env, obj.obj(), canvas);
524 void AwContents::PostInvalidate() {
525 JNIEnv* env = AttachCurrentThread();
526 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
527 if (!obj.is_null())
528 Java_AwContents_postInvalidateOnAnimation(env, obj.obj());
531 void AwContents::UpdateGlobalVisibleRect() {
532 JNIEnv* env = AttachCurrentThread();
533 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
534 if (!obj.is_null())
535 Java_AwContents_updateGlobalVisibleRect(env, obj.obj());
538 void AwContents::OnNewPicture() {
539 JNIEnv* env = AttachCurrentThread();
540 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
541 if (!obj.is_null())
542 Java_AwContents_onNewPicture(env, obj.obj());
545 base::android::ScopedJavaLocalRef<jbyteArray>
546 AwContents::GetCertificate(JNIEnv* env,
547 jobject obj) {
548 content::NavigationEntry* entry =
549 web_contents_->GetController().GetActiveEntry();
550 if (!entry)
551 return ScopedJavaLocalRef<jbyteArray>();
552 // Get the certificate
553 int cert_id = entry->GetSSL().cert_id;
554 scoped_refptr<net::X509Certificate> cert;
555 bool ok = content::CertStore::GetInstance()->RetrieveCert(cert_id, &cert);
556 if (!ok)
557 return ScopedJavaLocalRef<jbyteArray>();
559 // Convert the certificate and return it
560 std::string der_string;
561 net::X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_string);
562 return base::android::ToJavaByteArray(env,
563 reinterpret_cast<const uint8*>(der_string.data()), der_string.length());
566 void AwContents::RequestNewHitTestDataAt(JNIEnv* env, jobject obj,
567 jint x, jint y) {
568 render_view_host_ext_->RequestNewHitTestDataAt(x, y);
571 void AwContents::UpdateLastHitTestData(JNIEnv* env, jobject obj) {
572 if (!render_view_host_ext_->HasNewHitTestData()) return;
574 const AwHitTestData& data = render_view_host_ext_->GetLastHitTestData();
575 render_view_host_ext_->MarkHitTestDataRead();
577 // Make sure to null the Java object if data is empty/invalid.
578 ScopedJavaLocalRef<jstring> extra_data_for_type;
579 if (data.extra_data_for_type.length())
580 extra_data_for_type = ConvertUTF8ToJavaString(
581 env, data.extra_data_for_type);
583 ScopedJavaLocalRef<jstring> href;
584 if (data.href.length())
585 href = ConvertUTF16ToJavaString(env, data.href);
587 ScopedJavaLocalRef<jstring> anchor_text;
588 if (data.anchor_text.length())
589 anchor_text = ConvertUTF16ToJavaString(env, data.anchor_text);
591 ScopedJavaLocalRef<jstring> img_src;
592 if (data.img_src.is_valid())
593 img_src = ConvertUTF8ToJavaString(env, data.img_src.spec());
595 Java_AwContents_updateHitTestData(env,
596 obj,
597 data.type,
598 extra_data_for_type.obj(),
599 href.obj(),
600 anchor_text.obj(),
601 img_src.obj());
604 void AwContents::OnSizeChanged(JNIEnv* env, jobject obj,
605 int w, int h, int ow, int oh) {
606 browser_view_renderer_->OnSizeChanged(w, h);
609 void AwContents::SetVisibility(JNIEnv* env, jobject obj, bool visible) {
610 browser_view_renderer_->OnVisibilityChanged(visible);
613 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) {
614 browser_view_renderer_->OnAttachedToWindow(w, h);
617 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
618 browser_view_renderer_->OnDetachedFromWindow();
621 base::android::ScopedJavaLocalRef<jbyteArray>
622 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) {
623 // Required optimization in WebViewClassic to not save any state if
624 // there has been no navigations.
625 if (!web_contents_->GetController().GetEntryCount())
626 return ScopedJavaLocalRef<jbyteArray>();
628 Pickle pickle;
629 if (!WriteToPickle(*web_contents_, &pickle)) {
630 return ScopedJavaLocalRef<jbyteArray>();
631 } else {
632 return base::android::ToJavaByteArray(env,
633 reinterpret_cast<const uint8*>(pickle.data()), pickle.size());
637 jboolean AwContents::RestoreFromOpaqueState(
638 JNIEnv* env, jobject obj, jbyteArray state) {
639 // TODO(boliu): This copy can be optimized out if this is a performance
640 // problem.
641 std::vector<uint8> state_vector;
642 base::android::JavaByteArrayToByteVector(env, state, &state_vector);
644 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()),
645 state_vector.size());
646 PickleIterator iterator(pickle);
648 return RestoreFromPickle(&iterator, web_contents_.get());
651 bool AwContents::OnDraw(JNIEnv* env,
652 jobject obj,
653 jobject canvas,
654 jboolean is_hardware_accelerated,
655 jint scroll_x,
656 jint scroll_y,
657 jint clip_left,
658 jint clip_top,
659 jint clip_right,
660 jint clip_bottom) {
661 return browser_view_renderer_->OnDraw(
662 canvas,
663 is_hardware_accelerated,
664 gfx::Vector2d(scroll_x, scroll_y),
665 gfx::Rect(
666 clip_left, clip_top, clip_right - clip_left, clip_bottom - clip_top));
669 void AwContents::SetGlobalVisibleRect(JNIEnv* env,
670 jobject obj,
671 jint visible_left,
672 jint visible_top,
673 jint visible_right,
674 jint visible_bottom) {
675 browser_view_renderer_->SetGlobalVisibleRect(
676 gfx::Rect(visible_left,
677 visible_top,
678 visible_right - visible_left,
679 visible_bottom - visible_top));
682 void AwContents::SetPendingWebContentsForPopup(
683 scoped_ptr<content::WebContents> pending) {
684 if (pending_contents_.get()) {
685 // TODO(benm): Support holding multiple pop up window requests.
686 LOG(WARNING) << "Blocking popup window creation as an outstanding "
687 << "popup window is still pending.";
688 base::MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release());
689 return;
691 pending_contents_.reset(new AwContents(pending.Pass()));
694 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) {
695 web_contents_->FocusThroughTabTraversal(false);
698 void AwContents::SetBackgroundColor(JNIEnv* env, jobject obj, jint color) {
699 render_view_host_ext_->SetBackgroundColor(color);
702 jint AwContents::ReleasePopupAwContents(JNIEnv* env, jobject obj) {
703 return reinterpret_cast<jint>(pending_contents_.release());
706 gfx::Point AwContents::GetLocationOnScreen() {
707 JNIEnv* env = AttachCurrentThread();
708 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
709 if (obj.is_null())
710 return gfx::Point();
711 std::vector<int> location;
712 base::android::JavaIntArrayToIntVector(
713 env,
714 Java_AwContents_getLocationOnScreen(env, obj.obj()).obj(),
715 &location);
716 return gfx::Point(location[0], location[1]);
719 void AwContents::ScrollContainerViewTo(gfx::Vector2d new_value) {
720 JNIEnv* env = AttachCurrentThread();
721 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
722 if (obj.is_null())
723 return;
724 Java_AwContents_scrollContainerViewTo(
725 env, obj.obj(), new_value.x(), new_value.y());
729 void AwContents::DidOverscroll(gfx::Vector2d overscroll_delta) {
730 JNIEnv* env = AttachCurrentThread();
731 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
732 if (obj.is_null())
733 return;
734 Java_AwContents_didOverscroll(
735 env, obj.obj(), overscroll_delta.x(), overscroll_delta.y());
738 void AwContents::SetDipScale(JNIEnv* env, jobject obj, jfloat dipScale) {
739 browser_view_renderer_->SetDipScale(dipScale);
742 void AwContents::SetDisplayedPageScaleFactor(JNIEnv* env,
743 jobject obj,
744 jfloat pageScaleFactor) {
745 browser_view_renderer_->SetPageScaleFactor(pageScaleFactor);
748 void AwContents::ScrollTo(JNIEnv* env, jobject obj, jint xPix, jint yPix) {
749 browser_view_renderer_->ScrollTo(gfx::Vector2d(xPix, yPix));
752 void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) {
753 JNIEnv* env = AttachCurrentThread();
754 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
755 if (obj.is_null())
756 return;
757 Java_AwContents_onWebLayoutPageScaleFactorChanged(env, obj.obj(),
758 page_scale_factor);
761 ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env,
762 jobject obj,
763 int width,
764 int height) {
765 return browser_view_renderer_->CapturePicture(width, height);
768 void AwContents::EnableOnNewPicture(JNIEnv* env,
769 jobject obj,
770 jboolean enabled) {
771 browser_view_renderer_->EnableOnNewPicture(enabled);
774 } // namespace android_webview