From 80ba1a418107211ab9dd3cf3028d96b50ac78f44 Mon Sep 17 00:00:00 2001 From: Kaido Kert Date: Wed, 18 Dec 2024 18:33:39 -0800 Subject: [PATCH] Draft: Scaffold shell entry for Cobalt --- cobalt/__init__.py | 0 cobalt/android/BUILD.gn | 11 ++ cobalt/android/shell_manager.cc | 78 ++++++++ cobalt/android/shell_manager.h | 47 +++++ .../shell_platform_delegate_android.cc | 167 ++++++++++++++++++ ...hell_web_contents_view_delegate_android.cc | 33 ++++ cobalt/cobalt_shell.cc | 10 ++ cobalt/cobalt_shell.h | 15 ++ content/shell/BUILD.gn | 2 + 9 files changed, 363 insertions(+) create mode 100644 cobalt/__init__.py create mode 100644 cobalt/android/shell_manager.cc create mode 100644 cobalt/android/shell_manager.h create mode 100644 cobalt/android/shell_platform_delegate_android.cc create mode 100644 cobalt/android/shell_web_contents_view_delegate_android.cc create mode 100644 cobalt/cobalt_shell.cc create mode 100644 cobalt/cobalt_shell.h diff --git a/cobalt/__init__.py b/cobalt/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/cobalt/android/BUILD.gn b/cobalt/android/BUILD.gn index 85e5e0d69d75..22384e07c169 100644 --- a/cobalt/android/BUILD.gn +++ b/cobalt/android/BUILD.gn @@ -186,8 +186,19 @@ shared_library("libcobalt_content_shell_content_view") { "//cobalt/cobalt_content_browser_client.h", "//cobalt/cobalt_main_delegate.cc", "//cobalt/cobalt_main_delegate.h", + "//cobalt/cobalt_shell.cc", + "//cobalt/cobalt_shell.h", "cobalt_library_loader.cc", ] + + # Content shell Android parts + sources += [ + "//cobalt/android/shell_manager.cc", + "//cobalt/android/shell_manager.h", + "//cobalt/android/shell_platform_delegate_android.cc", + "//cobalt/android/shell_web_contents_view_delegate_android.cc", + ] + configs -= [ "//build/config/android:hide_all_but_jni_onload" ] configs += [ "//build/config/android:hide_all_but_jni" ] } diff --git a/cobalt/android/shell_manager.cc b/cobalt/android/shell_manager.cc new file mode 100644 index 000000000000..b812661a3aeb --- /dev/null +++ b/cobalt/android/shell_manager.cc @@ -0,0 +1,78 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cobalt/android/shell_manager.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/functional/bind.h" +#include "base/lazy_instance.h" +#include "cobalt/cobalt_shell.h" +#include "content/public/browser/web_contents.h" +#include "content/shell/android/content_shell_jni_headers/ShellManager_jni.h" +#include "content/shell/browser/shell_browser_context.h" +#include "content/shell/browser/shell_content_browser_client.h" +#include "url/gurl.h" + +// Note: Origin of this file is content/shell/shell_manager.cc from m114 + +using base::android::JavaParamRef; +using base::android::JavaRef; +using base::android::ScopedJavaLocalRef; + +namespace { + +struct GlobalState { + GlobalState() {} + base::android::ScopedJavaGlobalRef j_shell_manager; +}; + +base::LazyInstance::DestructorAtExit g_global_state = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +namespace cobalt { + +ScopedJavaLocalRef CreateShellView(content::Shell* shell) { + JNIEnv* env = base::android::AttachCurrentThread(); + return content::Java_ShellManager_createShell( + env, g_global_state.Get().j_shell_manager, + reinterpret_cast(shell)); +} + +void RemoveShellView(const JavaRef& shell_view) { + JNIEnv* env = base::android::AttachCurrentThread(); + content::Java_ShellManager_removeShell( + env, g_global_state.Get().j_shell_manager, shell_view); +} + +} // namespace cobalt + +// Note: Below tracks generated Java code, which is currently generated +// in content, not cobalt namespace. + +namespace content { + +static void JNI_ShellManager_Init(JNIEnv* env, + const JavaParamRef& obj) { + g_global_state.Get().j_shell_manager.Reset(obj); +} + +void JNI_ShellManager_LaunchShell(JNIEnv* env, + const JavaParamRef& jurl) { + content::ShellBrowserContext* browserContext = + content::ShellContentBrowserClient::Get()->browser_context(); + GURL url(base::android::ConvertJavaStringToUTF8(env, jurl)); + cobalt::CobaltShell::CreateNewWindow(browserContext, url, nullptr, + gfx::Size()); +} + +void DestroyShellManager() { + JNIEnv* env = base::android::AttachCurrentThread(); + content::Java_ShellManager_destroy(env, g_global_state.Get().j_shell_manager); +} + +} // namespace content diff --git a/cobalt/android/shell_manager.h b/cobalt/android/shell_manager.h new file mode 100644 index 000000000000..2ce57b8c2960 --- /dev/null +++ b/cobalt/android/shell_manager.h @@ -0,0 +1,47 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_SHELL_ANDROID_SHELL_MANAGER_H_ +#define CONTENT_SHELL_ANDROID_SHELL_MANAGER_H_ + +#include + +#include "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" + +// Note: Origin of this file is content/shell/shell_manager.h from m114 + +namespace content { +class Shell; +} + +namespace cc { +class Layer; +} + +namespace cobalt { + +// Creates an Android specific shell view, which is our version of a shell +// window. This view holds the controls and content views necessary to +// render a shell window. Returns the java object representing the shell view. +// object. +base::android::ScopedJavaLocalRef CreateShellView( + content::Shell* shell); + +// Removes a previously created shell view. +void RemoveShellView(const base::android::JavaRef& shell_view); + +} // namespace cobalt +namespace content { + +void ShellAttachLayer(cc::Layer* layer); +void ShellRemoveLayer(cc::Layer* layer); + +// Destroys the ShellManager on app exit. Must not use the above functions +// after this is called. +void DestroyShellManager(); + +} // namespace content + +#endif // CONTENT_SHELL_ANDROID_SHELL_MANAGER_H_ diff --git a/cobalt/android/shell_platform_delegate_android.cc b/cobalt/android/shell_platform_delegate_android.cc new file mode 100644 index 000000000000..f006124a907c --- /dev/null +++ b/cobalt/android/shell_platform_delegate_android.cc @@ -0,0 +1,167 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/shell/browser/shell_platform_delegate.h" + +#include + +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/command_line.h" +#include "base/containers/contains.h" +#include "base/notreached.h" +#include "base/strings/string_piece.h" +#include "cobalt/android/shell_manager.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "content/shell/android/content_shell_jni_headers/Shell_jni.h" +#include "content/shell/browser/shell.h" + +using base::android::AttachCurrentThread; +using base::android::ConvertUTF8ToJavaString; +using base::android::JavaParamRef; +using base::android::ScopedJavaLocalRef; + +namespace content { + +struct ShellPlatformDelegate::ShellData { + base::android::ScopedJavaGlobalRef java_object; +}; + +struct ShellPlatformDelegate::PlatformData {}; + +ShellPlatformDelegate::ShellPlatformDelegate() = default; + +void ShellPlatformDelegate::Initialize(const gfx::Size& default_window_size) { + // |platform_| is not used on this platform. +} + +ShellPlatformDelegate::~ShellPlatformDelegate() { + content::DestroyShellManager(); +} + +void ShellPlatformDelegate::CreatePlatformWindow( + Shell* shell, + const gfx::Size& initial_size) { + DCHECK(!base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + shell_data.java_object.Reset(cobalt::CreateShellView(shell)); +} + +void ShellPlatformDelegate::CleanUp(Shell* shell) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + cobalt::RemoveShellView(shell_data.java_object); + + if (!shell_data.java_object.is_null()) { + Java_Shell_onNativeDestroyed(env, shell_data.java_object); + } + + shell_data_map_.erase(shell); +} + +void ShellPlatformDelegate::SetContents(Shell* shell) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + Java_Shell_initFromNativeTabContents( + env, shell_data.java_object, shell->web_contents()->GetJavaWebContents()); +} + +void ShellPlatformDelegate::ResizeWebContent(Shell* shell, + const gfx::Size& content_size) { + shell->web_contents()->GetRenderWidgetHostView()->SetSize(content_size); +} + +void ShellPlatformDelegate::EnableUIControl(Shell* shell, + UIControl control, + bool is_enabled) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + if (shell_data.java_object.is_null()) { + return; + } + Java_Shell_enableUiControl(env, shell_data.java_object, control, is_enabled); +} + +void ShellPlatformDelegate::SetAddressBarURL(Shell* shell, const GURL& url) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + ScopedJavaLocalRef j_url = ConvertUTF8ToJavaString(env, url.spec()); + Java_Shell_onUpdateUrl(env, shell_data.java_object, j_url); +} + +void ShellPlatformDelegate::SetIsLoading(Shell* shell, bool loading) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + Java_Shell_setIsLoading(env, shell_data.java_object, loading); +} + +void ShellPlatformDelegate::SetTitle(Shell* shell, + const std::u16string& title) {} + +void ShellPlatformDelegate::MainFrameCreated(Shell* shell) {} + +bool ShellPlatformDelegate::DestroyShell(Shell* shell) { + return false; // Shell destroys itself. +} + +void ShellPlatformDelegate::ToggleFullscreenModeForTab( + Shell* shell, + WebContents* web_contents, + bool enter_fullscreen) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + Java_Shell_toggleFullscreenModeForTab(env, shell_data.java_object, + enter_fullscreen); +} + +bool ShellPlatformDelegate::IsFullscreenForTabOrPending( + Shell* shell, + const WebContents* web_contents) const { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + const ShellData& shell_data = shell_data_map_.find(shell)->second; + + return Java_Shell_isFullscreenForTabOrPending(env, shell_data.java_object); +} + +void ShellPlatformDelegate::SetOverlayMode(Shell* shell, + bool use_overlay_mode) { + JNIEnv* env = base::android::AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + return Java_Shell_setOverlayMode(env, shell_data.java_object, + use_overlay_mode); +} + +void ShellPlatformDelegate::LoadProgressChanged(Shell* shell, double progress) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(base::Contains(shell_data_map_, shell)); + ShellData& shell_data = shell_data_map_[shell]; + + Java_Shell_onLoadProgressChanged(env, shell_data.java_object, progress); +} + +// static +void JNI_Shell_CloseShell(JNIEnv* env, jlong shellPtr) { + Shell* shell = reinterpret_cast(shellPtr); + shell->Close(); +} + +} // namespace content diff --git a/cobalt/android/shell_web_contents_view_delegate_android.cc b/cobalt/android/shell_web_contents_view_delegate_android.cc new file mode 100644 index 000000000000..e024485af414 --- /dev/null +++ b/cobalt/android/shell_web_contents_view_delegate_android.cc @@ -0,0 +1,33 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/shell/browser/shell_web_contents_view_delegate.h" + +#include + +#include "base/command_line.h" +#include "content/public/browser/context_menu_params.h" +#include "content/public/browser/web_contents.h" +#include "content/shell/browser/shell_web_contents_view_delegate_creator.h" + +namespace content { + +std::unique_ptr CreateShellWebContentsViewDelegate( + WebContents* web_contents) { + return std::make_unique(web_contents); +} + +ShellWebContentsViewDelegate::ShellWebContentsViewDelegate( + WebContents* web_contents) + : web_contents_(web_contents) { + DCHECK(web_contents_); // Avoids 'unused private field' build error. +} + +ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() {} + +void ShellWebContentsViewDelegate::ShowContextMenu( + RenderFrameHost& render_frame_host, + const ContextMenuParams& params) {} + +} // namespace content diff --git a/cobalt/cobalt_shell.cc b/cobalt/cobalt_shell.cc new file mode 100644 index 000000000000..d17e75be861d --- /dev/null +++ b/cobalt/cobalt_shell.cc @@ -0,0 +1,10 @@ +#include "cobalt/cobalt_shell.h" + +namespace cobalt { + +// Placeholder for a WebContentsObserver override +void CobaltShell::PrimaryMainDocumentElementAvailable() { + LOG(INFO) << "Cobalt::PrimaryMainDocumentElementAvailable"; +} + +} // namespace cobalt diff --git a/cobalt/cobalt_shell.h b/cobalt/cobalt_shell.h new file mode 100644 index 000000000000..217f7fab6076 --- /dev/null +++ b/cobalt/cobalt_shell.h @@ -0,0 +1,15 @@ +#ifndef COBALT_COBALT_SHELL_H +#define COBALT_COBALT_SHELL_H + +#include "content/shell/browser/shell.h" + +namespace cobalt { + +class CobaltShell : public content::Shell { + // WebContentsObserver + void PrimaryMainDocumentElementAvailable() override; +}; + +} // namespace cobalt + +#endif // COBALT_COBALT_SHELL_H diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 0c169741a534..c9a6031bd98d 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn @@ -192,12 +192,14 @@ static_library("content_shell_lib") { ] if (is_android) { + if (!is_cobalt) { sources += [ "android/shell_manager.cc", "android/shell_manager.h", "browser/shell_platform_delegate_android.cc", "browser/shell_web_contents_view_delegate_android.cc", ] + } } if (is_mac) {