1 // Copyright 2019 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 "components/thin_webview/internal/thin_webview.h"
6
7 #include "base/android/jni_android.h"
8 #include "cc/layers/layer.h"
9 #include "components/embedder_support/android/delegate/web_contents_delegate_android.h"
10 #include "components/thin_webview/internal/jni_headers/ThinWebViewImpl_jni.h"
11 #include "components/thin_webview/thin_webview_initializer.h"
12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/common/browser_controls_state.h"
15
16 using base::android::JavaParamRef;
17 using web_contents_delegate_android::WebContentsDelegateAndroid;
18
19 namespace thin_webview {
20 namespace android {
21
JNI_ThinWebViewImpl_Init(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & jcompositor_view,const JavaParamRef<jobject> & jwindow_android)22 jlong JNI_ThinWebViewImpl_Init(JNIEnv* env,
23 const JavaParamRef<jobject>& obj,
24 const JavaParamRef<jobject>& jcompositor_view,
25 const JavaParamRef<jobject>& jwindow_android) {
26 CompositorView* compositor_view =
27 CompositorViewImpl::FromJavaObject(jcompositor_view);
28 ui::WindowAndroid* window_android =
29 ui::WindowAndroid::FromJavaWindowAndroid(jwindow_android);
30 ThinWebView* view =
31 new ThinWebView(env, obj, compositor_view, window_android);
32 return reinterpret_cast<intptr_t>(view);
33 }
34
ThinWebView(JNIEnv * env,jobject obj,CompositorView * compositor_view,ui::WindowAndroid * window_android)35 ThinWebView::ThinWebView(JNIEnv* env,
36 jobject obj,
37 CompositorView* compositor_view,
38 ui::WindowAndroid* window_android)
39 : obj_(env, obj),
40 compositor_view_(compositor_view),
41 window_android_(window_android),
42 web_contents_(nullptr) {}
43
~ThinWebView()44 ThinWebView::~ThinWebView() {}
45
Destroy(JNIEnv * env,const JavaParamRef<jobject> & object)46 void ThinWebView::Destroy(JNIEnv* env, const JavaParamRef<jobject>& object) {
47 delete this;
48 }
49
SetWebContents(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & jweb_contents,const JavaParamRef<jobject> & jweb_contents_delegate)50 void ThinWebView::SetWebContents(
51 JNIEnv* env,
52 const JavaParamRef<jobject>& obj,
53 const JavaParamRef<jobject>& jweb_contents,
54 const JavaParamRef<jobject>& jweb_contents_delegate) {
55 content::WebContents* web_contents =
56 content::WebContents::FromJavaWebContents(jweb_contents);
57 WebContentsDelegateAndroid* delegate =
58 jweb_contents_delegate.is_null()
59 ? nullptr
60 : new WebContentsDelegateAndroid(env, jweb_contents_delegate);
61 SetWebContents(web_contents, delegate);
62 }
63
SetWebContents(content::WebContents * web_contents,WebContentsDelegateAndroid * delegate)64 void ThinWebView::SetWebContents(content::WebContents* web_contents,
65 WebContentsDelegateAndroid* delegate) {
66 DCHECK(web_contents);
67 web_contents_ = web_contents;
68 ui::ViewAndroid* view_android = web_contents_->GetNativeView();
69 if (view_android->parent() != window_android_) {
70 window_android_->AddChild(view_android);
71 }
72
73 compositor_view_->SetRootLayer(web_contents_->GetNativeView()->GetLayer());
74 ResizeWebContents(view_size_);
75 web_contents_delegate_.reset(delegate);
76 if (delegate)
77 web_contents->SetDelegate(delegate);
78
79 ThinWebViewInitializer::GetInstance()->AttachTabHelpers(web_contents);
80
81 // Disable browser controls when used for thin webview.
82 web_contents->GetMainFrame()->UpdateBrowserControlsState(
83 content::BROWSER_CONTROLS_STATE_HIDDEN,
84 content::BROWSER_CONTROLS_STATE_HIDDEN, false);
85 }
86
SizeChanged(JNIEnv * env,const JavaParamRef<jobject> & object,jint width,jint height)87 void ThinWebView::SizeChanged(JNIEnv* env,
88 const JavaParamRef<jobject>& object,
89 jint width,
90 jint height) {
91 view_size_ = gfx::Size(width, height);
92
93 // TODO(shaktisahu): If we want to use a different size for WebContents, e.g.
94 // showing full screen contents instead inside this view, don't do the resize.
95 if (web_contents_)
96 ResizeWebContents(view_size_);
97 }
98
ResizeWebContents(const gfx::Size & size)99 void ThinWebView::ResizeWebContents(const gfx::Size& size) {
100 if (!web_contents_)
101 return;
102
103 web_contents_->GetNativeView()->OnPhysicalBackingSizeChanged(size);
104 web_contents_->GetNativeView()->OnSizeChanged(size.width(), size.height());
105 }
106
107 } // namespace android
108 } // namespace thin_webview
109