| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/thin_webview/internal/thin_webview.h" |
| |
| #include "base/android/jni_android.h" |
| #include "cc/input/browser_controls_state.h" |
| #include "cc/slim/layer.h" |
| #include "components/embedder_support/android/delegate/web_contents_delegate_android.h" |
| #include "components/thin_webview/internal/jni_headers/ThinWebViewImpl_jni.h" |
| #include "components/thin_webview/thin_webview_initializer.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/web_contents.h" |
| |
| using base::android::JavaParamRef; |
| using web_contents_delegate_android::WebContentsDelegateAndroid; |
| |
| namespace thin_webview { |
| namespace android { |
| |
| jlong JNI_ThinWebViewImpl_Init(JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jobject>& jcompositor_view, |
| const JavaParamRef<jobject>& jwindow_android) { |
| CompositorView* compositor_view = |
| CompositorViewImpl::FromJavaObject(jcompositor_view); |
| ui::WindowAndroid* window_android = |
| ui::WindowAndroid::FromJavaWindowAndroid(jwindow_android); |
| ThinWebView* view = |
| new ThinWebView(env, obj, compositor_view, window_android); |
| return reinterpret_cast<intptr_t>(view); |
| } |
| |
| ThinWebView::ThinWebView(JNIEnv* env, |
| jobject obj, |
| CompositorView* compositor_view, |
| ui::WindowAndroid* window_android) |
| : obj_(env, obj), |
| compositor_view_(compositor_view), |
| window_android_(window_android), |
| web_contents_(nullptr) {} |
| |
| ThinWebView::~ThinWebView() {} |
| |
| void ThinWebView::Destroy(JNIEnv* env, const JavaParamRef<jobject>& object) { |
| delete this; |
| } |
| |
| void ThinWebView::PrimaryPageChanged(content::Page& page) { |
| // Disable browser controls when used for thin webview. |
| web_contents_->UpdateBrowserControlsState(cc::BrowserControlsState::kHidden, |
| cc::BrowserControlsState::kHidden, |
| false); |
| } |
| |
| void ThinWebView::SetWebContents( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jobject>& jweb_contents, |
| const JavaParamRef<jobject>& jweb_contents_delegate) { |
| content::WebContents* web_contents = |
| content::WebContents::FromJavaWebContents(jweb_contents); |
| WebContentsDelegateAndroid* delegate = |
| jweb_contents_delegate.is_null() |
| ? nullptr |
| : new WebContentsDelegateAndroid(env, jweb_contents_delegate); |
| SetWebContents(web_contents, delegate); |
| } |
| |
| void ThinWebView::SetWebContents(content::WebContents* web_contents, |
| WebContentsDelegateAndroid* delegate) { |
| DCHECK(web_contents); |
| web_contents_ = web_contents; |
| Observe(web_contents_); |
| ui::ViewAndroid* view_android = web_contents_->GetNativeView(); |
| if (view_android->parent() != window_android_) { |
| window_android_->AddChild(view_android); |
| } |
| |
| compositor_view_->SetRootLayer(web_contents_->GetNativeView()->GetLayer()); |
| ResizeWebContents(view_size_); |
| web_contents_delegate_.reset(delegate); |
| if (delegate) |
| web_contents->SetDelegate(delegate); |
| |
| ThinWebViewInitializer::GetInstance()->AttachTabHelpers(web_contents); |
| } |
| |
| void ThinWebView::SizeChanged(JNIEnv* env, |
| const JavaParamRef<jobject>& object, |
| jint width, |
| jint height) { |
| view_size_ = gfx::Size(width, height); |
| |
| // TODO(shaktisahu): If we want to use a different size for WebContents, e.g. |
| // showing full screen contents instead inside this view, don't do the resize. |
| if (web_contents_) |
| ResizeWebContents(view_size_); |
| } |
| |
| void ThinWebView::ResizeWebContents(const gfx::Size& size) { |
| if (!web_contents_) |
| return; |
| |
| web_contents_->GetNativeView()->OnPhysicalBackingSizeChanged(size); |
| web_contents_->GetNativeView()->OnSizeChanged(size.width(), size.height()); |
| } |
| |
| } // namespace android |
| } // namespace thin_webview |