Skip to content

Commit

Permalink
Draft: Scaffold shell entry for Cobalt
Browse files Browse the repository at this point in the history
  • Loading branch information
kaidokert committed Dec 19, 2024
1 parent 9158f9a commit 80ba1a4
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 0 deletions.
Empty file added cobalt/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions cobalt/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
}
Expand Down
78 changes: 78 additions & 0 deletions cobalt/android/shell_manager.cc
Original file line number Diff line number Diff line change
@@ -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<jobject> j_shell_manager;
};

base::LazyInstance<GlobalState>::DestructorAtExit g_global_state =
LAZY_INSTANCE_INITIALIZER;

} // namespace

namespace cobalt {

ScopedJavaLocalRef<jobject> CreateShellView(content::Shell* shell) {
JNIEnv* env = base::android::AttachCurrentThread();
return content::Java_ShellManager_createShell(
env, g_global_state.Get().j_shell_manager,
reinterpret_cast<intptr_t>(shell));
}

void RemoveShellView(const JavaRef<jobject>& 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<jobject>& obj) {
g_global_state.Get().j_shell_manager.Reset(obj);
}

void JNI_ShellManager_LaunchShell(JNIEnv* env,
const JavaParamRef<jstring>& 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
47 changes: 47 additions & 0 deletions cobalt/android/shell_manager.h
Original file line number Diff line number Diff line change
@@ -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 <jni.h>

#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<jobject> CreateShellView(
content::Shell* shell);

// Removes a previously created shell view.
void RemoveShellView(const base::android::JavaRef<jobject>& 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_
167 changes: 167 additions & 0 deletions cobalt/android/shell_platform_delegate_android.cc
Original file line number Diff line number Diff line change
@@ -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 <jni.h>

#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<jobject> 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<jstring> 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<Shell*>(shellPtr);
shell->Close();
}

} // namespace content
33 changes: 33 additions & 0 deletions cobalt/android/shell_web_contents_view_delegate_android.cc
Original file line number Diff line number Diff line change
@@ -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 <memory>

#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<WebContentsViewDelegate> CreateShellWebContentsViewDelegate(
WebContents* web_contents) {
return std::make_unique<ShellWebContentsViewDelegate>(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
10 changes: 10 additions & 0 deletions cobalt/cobalt_shell.cc
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions cobalt/cobalt_shell.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions content/shell/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 80ba1a4

Please sign in to comment.