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