aw_contents.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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 "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" 51 52struct AwDrawSWFunctionTable; 53struct AwDrawGLFunctionTable; 54 55using autofill::AutofillDriverImpl; 56using autofill::AutofillManager; 57using base::android::AttachCurrentThread; 58using base::android::ConvertJavaStringToUTF16; 59using base::android::ConvertJavaStringToUTF8; 60using base::android::ConvertUTF16ToJavaString; 61using base::android::ConvertUTF8ToJavaString; 62using base::android::JavaRef; 63using base::android::ScopedJavaGlobalRef; 64using base::android::ScopedJavaLocalRef; 65using navigation_interception::InterceptNavigationDelegate; 66using content::BrowserThread; 67using content::ContentViewCore; 68using content::WebContents; 69 70extern "C" { 71static AwDrawGLFunction DrawGLFunction; 72static 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); 79} 80} 81 82namespace android_webview { 83 84namespace { 85 86JavaBrowserViewRendererHelper* java_renderer_helper() { 87 static JavaBrowserViewRendererHelper* g_instance 88 = new JavaBrowserViewRendererHelper; 89 return g_instance; 90} 91 92const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; 93 94class AwContentsUserData : public base::SupportsUserData::Data { 95 public: 96 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} 97 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; 104 } 105 106 private: 107 AwContents* contents_; 108}; 109 110base::subtle::Atomic32 g_instance_count = 0; 111 112} // namespace 113 114// static 115AwContents* AwContents::FromWebContents(WebContents* web_contents) { 116 return AwContentsUserData::GetContents(web_contents); 117} 118 119// static 120AwContents* 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); 129} 130 131AwContents::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())); 143 144 AwAutofillManagerDelegate* autofill_manager_delegate = 145 AwAutofillManagerDelegate::FromWebContents(web_contents_.get()); 146 if (autofill_manager_delegate) 147 InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData()); 148} 149 150void 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); 161 162 web_contents_delegate_.reset( 163 new AwWebContentsDelegate(env, web_contents_delegate)); 164 web_contents_->SetDelegate(web_contents_delegate_.get()); 165 166 contents_client_bridge_.reset( 167 new AwContentsClientBridge(env, contents_client_bridge)); 168 AwContentsClientBridgeBase::Associate(web_contents_.get(), 169 contents_client_bridge_.get()); 170 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); 176 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 178 InterceptNavigationDelegate::Associate( 179 web_contents_.get(), 180 make_scoped_ptr(new InterceptNavigationDelegate( 181 env, intercept_navigation_delegate))); 182} 183 184void 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); 191 } 192} 193 194void 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; 202 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); 211} 212 213void 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); 219} 220 221AwContents::~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); 229} 230 231jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { 232 DCHECK(web_contents_); 233 return reinterpret_cast<jint>(web_contents_.get()); 234} 235 236void AwContents::Destroy(JNIEnv* env, jobject obj) { 237 delete this; 238} 239 240static 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())); 248} 249 250static void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { 251 BrowserViewRenderer::SetAwDrawSWFunctionTable( 252 reinterpret_cast<AwDrawSWFunctionTable*>(function_table)); 253} 254 255static void SetAwDrawGLFunctionTable(JNIEnv* env, jclass, jint function_table) { 256 GpuMemoryBufferFactoryImpl::SetAwDrawGLFunctionTable( 257 reinterpret_cast<AwDrawGLFunctionTable*>(function_table)); 258} 259 260static jint GetAwDrawGLFunction(JNIEnv* env, jclass) { 261 return reinterpret_cast<jint>(&DrawGLFunction); 262} 263 264// static 265jint GetNativeInstanceCount(JNIEnv* env, jclass) { 266 return base::subtle::NoBarrier_Load(&g_instance_count); 267} 268 269jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { 270 return reinterpret_cast<jint>(browser_view_renderer_.get()); 271} 272 273namespace { 274void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message, 275 bool has_images) { 276 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), 277 has_images, 278 message.obj()); 279} 280} // namespace 281 282void 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)); 287} 288 289namespace { 290void 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()); 298} 299} // namespace 300 301void 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))); 308} 309 310void AwContents::PerformLongClick() { 311 JNIEnv* env = AttachCurrentThread(); 312 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 313 if (obj.is_null()) 314 return; 315 316 Java_AwContents_performLongClick(env, obj.obj()); 317} 318 319bool 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; 326 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; 332} 333 334void 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); 341 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)); 347 } 348 349 AwBrowserContext::FromWebContents(web_contents_.get()) 350 ->AddVisitedURLs(visited_link_gurls); 351} 352 353bool RegisterAwContents(JNIEnv* env) { 354 return RegisterNativesImpl(env) >= 0; 355} 356 357namespace { 358 359void 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()); 369 } 370} 371 372void 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)); 382 } 383} 384 385} // anonymous namespace 386 387void 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); 394 } 395} 396 397// Invoked from Java 398void 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); 410 } 411 } 412} 413 414void 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; 421 } 422 it = pending_geolocation_prompts_.erase(it); 423 } else { 424 ++it; 425 } 426 } 427 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()); 433 } 434 if (!pending_geolocation_prompts_.empty()) { 435 ShowGeolocationPromptHelper(java_ref_, 436 pending_geolocation_prompts_.front().first); 437 } 438 } 439} 440 441void AwContents::FindAllAsync(JNIEnv* env, jobject obj, jstring search_string) { 442 GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string)); 443} 444 445void AwContents::FindNext(JNIEnv* env, jobject obj, jboolean forward) { 446 GetFindHelper()->FindNext(forward); 447} 448 449void AwContents::ClearMatches(JNIEnv* env, jobject obj) { 450 GetFindHelper()->ClearMatches(); 451} 452 453void 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(); 459 460 if (include_disk_files) { 461 RemoveHttpDiskCache(web_contents_->GetBrowserContext(), 462 web_contents_->GetRoutingID()); 463 } 464} 465 466FindHelper* AwContents::GetFindHelper() { 467 if (!find_helper_.get()) { 468 find_helper_.reset(new FindHelper(web_contents_.get())); 469 find_helper_->SetListener(this); 470 } 471 return find_helper_.get(); 472} 473 474void 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; 481 482 Java_AwContents_onFindResultReceived( 483 env, obj.obj(), active_ordinal, match_count, finished); 484} 485 486void 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; 491 492 content::NavigationEntry* entry = 493 web_contents_->GetController().GetActiveEntry(); 494 495 if (entry) { 496 entry->GetFavicon().valid = true; 497 entry->GetFavicon().url = icon_url; 498 entry->GetFavicon().image = gfx::Image::CreateFrom1xBitmap(bitmap); 499 } 500 501 Java_AwContents_onReceivedIcon( 502 env, obj.obj(), gfx::ConvertToJavaBitmap(&bitmap).obj()); 503} 504 505void 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; 511 512 Java_AwContents_onReceivedTouchIconUrl( 513 env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed); 514} 515 516bool 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); 522} 523 524void 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()); 529} 530 531void AwContents::OnNewPicture() { 532 JNIEnv* env = AttachCurrentThread(); 533 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 534 if (!obj.is_null()) 535 Java_AwContents_onNewPicture(env, obj.obj()); 536} 537 538base::android::ScopedJavaLocalRef<jbyteArray> 539 AwContents::GetCertificate(JNIEnv* env, 540 jobject obj) { 541 content::NavigationEntry* entry = 542 web_contents_->GetController().GetActiveEntry(); 543 if (!entry) 544 return ScopedJavaLocalRef<jbyteArray>(); 545 // Get the certificate 546 int cert_id = entry->GetSSL().cert_id; 547 scoped_refptr<net::X509Certificate> cert; 548 bool ok = content::CertStore::GetInstance()->RetrieveCert(cert_id, &cert); 549 if (!ok) 550 return ScopedJavaLocalRef<jbyteArray>(); 551 552 // Convert the certificate and return it 553 std::string der_string; 554 net::X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_string); 555 return base::android::ToJavaByteArray(env, 556 reinterpret_cast<const uint8*>(der_string.data()), der_string.length()); 557} 558 559void AwContents::RequestNewHitTestDataAt(JNIEnv* env, jobject obj, 560 jint x, jint y) { 561 render_view_host_ext_->RequestNewHitTestDataAt(x, y); 562} 563 564void AwContents::UpdateLastHitTestData(JNIEnv* env, jobject obj) { 565 if (!render_view_host_ext_->HasNewHitTestData()) return; 566 567 const AwHitTestData& data = render_view_host_ext_->GetLastHitTestData(); 568 render_view_host_ext_->MarkHitTestDataRead(); 569 570 // Make sure to null the Java object if data is empty/invalid. 571 ScopedJavaLocalRef<jstring> extra_data_for_type; 572 if (data.extra_data_for_type.length()) 573 extra_data_for_type = ConvertUTF8ToJavaString( 574 env, data.extra_data_for_type); 575 576 ScopedJavaLocalRef<jstring> href; 577 if (data.href.length()) 578 href = ConvertUTF16ToJavaString(env, data.href); 579 580 ScopedJavaLocalRef<jstring> anchor_text; 581 if (data.anchor_text.length()) 582 anchor_text = ConvertUTF16ToJavaString(env, data.anchor_text); 583 584 ScopedJavaLocalRef<jstring> img_src; 585 if (data.img_src.is_valid()) 586 img_src = ConvertUTF8ToJavaString(env, data.img_src.spec()); 587 588 Java_AwContents_updateHitTestData(env, 589 obj, 590 data.type, 591 extra_data_for_type.obj(), 592 href.obj(), 593 anchor_text.obj(), 594 img_src.obj()); 595} 596 597void AwContents::OnSizeChanged(JNIEnv* env, jobject obj, 598 int w, int h, int ow, int oh) { 599 browser_view_renderer_->OnSizeChanged(w, h); 600} 601 602void AwContents::SetVisibility(JNIEnv* env, jobject obj, bool visible) { 603 browser_view_renderer_->OnVisibilityChanged(visible); 604} 605 606void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { 607 browser_view_renderer_->OnAttachedToWindow(w, h); 608} 609 610void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { 611 browser_view_renderer_->OnDetachedFromWindow(); 612} 613 614base::android::ScopedJavaLocalRef<jbyteArray> 615AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { 616 // Required optimization in WebViewClassic to not save any state if 617 // there has been no navigations. 618 if (!web_contents_->GetController().GetEntryCount()) 619 return ScopedJavaLocalRef<jbyteArray>(); 620 621 Pickle pickle; 622 if (!WriteToPickle(*web_contents_, &pickle)) { 623 return ScopedJavaLocalRef<jbyteArray>(); 624 } else { 625 return base::android::ToJavaByteArray(env, 626 reinterpret_cast<const uint8*>(pickle.data()), pickle.size()); 627 } 628} 629 630jboolean AwContents::RestoreFromOpaqueState( 631 JNIEnv* env, jobject obj, jbyteArray state) { 632 // TODO(boliu): This copy can be optimized out if this is a performance 633 // problem. 634 std::vector<uint8> state_vector; 635 base::android::JavaByteArrayToByteVector(env, state, &state_vector); 636 637 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()), 638 state_vector.size()); 639 PickleIterator iterator(pickle); 640 641 return RestoreFromPickle(&iterator, web_contents_.get()); 642} 643 644bool AwContents::OnDraw(JNIEnv* env, 645 jobject obj, 646 jobject canvas, 647 jboolean is_hardware_accelerated, 648 jint scroll_x, 649 jint scroll_y, 650 jint clip_left, 651 jint clip_top, 652 jint clip_right, 653 jint clip_bottom, 654 jint visible_left, 655 jint visible_top, 656 jint visible_right, 657 jint visible_bottom) { 658 return browser_view_renderer_->OnDraw( 659 canvas, 660 is_hardware_accelerated, 661 gfx::Vector2d(scroll_x, scroll_y), 662 gfx::Rect( 663 clip_left, clip_top, clip_right - clip_left, clip_bottom - clip_top), 664 gfx::Rect(visible_left, 665 visible_top, 666 visible_right - visible_left, 667 visible_bottom - visible_top)); 668} 669 670void AwContents::SetPendingWebContentsForPopup( 671 scoped_ptr<content::WebContents> pending) { 672 if (pending_contents_.get()) { 673 // TODO(benm): Support holding multiple pop up window requests. 674 LOG(WARNING) << "Blocking popup window creation as an outstanding " 675 << "popup window is still pending."; 676 base::MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release()); 677 return; 678 } 679 pending_contents_.reset(new AwContents(pending.Pass())); 680} 681 682void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { 683 web_contents_->FocusThroughTabTraversal(false); 684} 685 686void AwContents::SetBackgroundColor(JNIEnv* env, jobject obj, jint color) { 687 render_view_host_ext_->SetBackgroundColor(color); 688} 689 690jint AwContents::ReleasePopupAwContents(JNIEnv* env, jobject obj) { 691 return reinterpret_cast<jint>(pending_contents_.release()); 692} 693 694gfx::Point AwContents::GetLocationOnScreen() { 695 JNIEnv* env = AttachCurrentThread(); 696 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 697 if (obj.is_null()) 698 return gfx::Point(); 699 std::vector<int> location; 700 base::android::JavaIntArrayToIntVector( 701 env, 702 Java_AwContents_getLocationOnScreen(env, obj.obj()).obj(), 703 &location); 704 return gfx::Point(location[0], location[1]); 705} 706 707void AwContents::ScrollContainerViewTo(gfx::Vector2d new_value) { 708 JNIEnv* env = AttachCurrentThread(); 709 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 710 if (obj.is_null()) 711 return; 712 Java_AwContents_scrollContainerViewTo( 713 env, obj.obj(), new_value.x(), new_value.y()); 714} 715 716 717void AwContents::DidOverscroll(gfx::Vector2d overscroll_delta) { 718 JNIEnv* env = AttachCurrentThread(); 719 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 720 if (obj.is_null()) 721 return; 722 Java_AwContents_didOverscroll( 723 env, obj.obj(), overscroll_delta.x(), overscroll_delta.y()); 724} 725 726void AwContents::SetDipScale(JNIEnv* env, jobject obj, jfloat dipScale) { 727 browser_view_renderer_->SetDipScale(dipScale); 728} 729 730void AwContents::SetDisplayedPageScaleFactor(JNIEnv* env, 731 jobject obj, 732 jfloat pageScaleFactor) { 733 browser_view_renderer_->SetPageScaleFactor(pageScaleFactor); 734} 735 736void AwContents::ScrollTo(JNIEnv* env, jobject obj, jint xPix, jint yPix) { 737 browser_view_renderer_->ScrollTo(gfx::Vector2d(xPix, yPix)); 738} 739 740void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) { 741 JNIEnv* env = AttachCurrentThread(); 742 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 743 if (obj.is_null()) 744 return; 745 Java_AwContents_onWebLayoutPageScaleFactorChanged(env, obj.obj(), 746 page_scale_factor); 747} 748 749ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env, 750 jobject obj, 751 int width, 752 int height) { 753 return browser_view_renderer_->CapturePicture(width, height); 754} 755 756void AwContents::EnableOnNewPicture(JNIEnv* env, 757 jobject obj, 758 jboolean enabled) { 759 browser_view_renderer_->EnableOnNewPicture(enabled); 760} 761 762} // namespace android_webview 763