Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the Android splash screen logic #92965

Merged
merged 2 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2896,7 +2896,7 @@ Error Main::setup2() {

MAIN_PRINT("Main: Setup Logo");

#if !defined(TOOLS_ENABLED) && (defined(WEB_ENABLED) || defined(ANDROID_ENABLED))
#if !defined(TOOLS_ENABLED) && defined(WEB_ENABLED)
bool show_logo = false;
#else
bool show_logo = true;
Expand Down
131 changes: 12 additions & 119 deletions platform/android/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,6 @@ static const char *android_perms[] = {

static const char *MISMATCHED_VERSIONS_MESSAGE = "Android build version mismatch:\n| Template installed: %s\n| Requested version: %s\nPlease reinstall Android build template from 'Project' menu.";

static const char *SPLASH_IMAGE_EXPORT_PATH = "res/drawable-nodpi/splash.png";
static const char *LEGACY_BUILD_SPLASH_IMAGE_EXPORT_PATH = "res/drawable-nodpi-v4/splash.png";
static const char *SPLASH_BG_COLOR_PATH = "res/drawable-nodpi/splash_bg_color.png";
static const char *LEGACY_BUILD_SPLASH_BG_COLOR_PATH = "res/drawable-nodpi-v4/splash_bg_color.png";
static const char *SPLASH_CONFIG_PATH = "res/drawable/splash_drawable.xml";
static const char *GDEXTENSION_LIBS_PATH = "libs/gdextensionlibs.json";

static const int icon_densities_count = 6;
Expand Down Expand Up @@ -1642,67 +1637,6 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n
}
}

String EditorExportPlatformAndroid::load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) {
bool scale_splash = GLOBAL_GET("application/boot_splash/fullsize");
bool apply_filter = GLOBAL_GET("application/boot_splash/use_filter");
bool show_splash_image = GLOBAL_GET("application/boot_splash/show_image");
String project_splash_path = GLOBAL_GET("application/boot_splash/image");

// Setup the splash bg color.
bool bg_color_valid = false;
Color bg_color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color", &bg_color_valid);
if (!bg_color_valid) {
bg_color = boot_splash_bg_color;
}

if (show_splash_image) {
if (!project_splash_path.is_empty()) {
splash_image.instantiate();
print_verbose("Loading splash image: " + project_splash_path);
const Error err = ImageLoader::load_image(project_splash_path, splash_image);
if (err) {
if (OS::get_singleton()->is_stdout_verbose()) {
print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")");
}
splash_image.unref();
}
}
} else {
splash_image.instantiate();
splash_image->initialize_data(1, 1, false, Image::FORMAT_RGBA8);
splash_image->set_pixel(0, 0, bg_color);
}

if (splash_image.is_null()) {
// Use the default
print_verbose("Using default splash image.");
splash_image = Ref<Image>(memnew(Image(boot_splash_png)));
}

if (scale_splash) {
Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
int width, height;
if (screen_size.width > screen_size.height) {
// scale horizontally
height = screen_size.height;
width = splash_image->get_width() * screen_size.height / splash_image->get_height();
} else {
// scale vertically
width = screen_size.width;
height = splash_image->get_height() * screen_size.width / splash_image->get_width();
}
splash_image->resize(width, height);
}

print_verbose("Creating splash background color image.");
splash_bg_color_image.instantiate();
splash_bg_color_image->initialize_data(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format());
splash_bg_color_image->fill(bg_color);

String processed_splash_config_xml = vformat(SPLASH_CONFIG_XML_CONTENT, bool_to_string(apply_filter));
return processed_splash_config_xml;
}

void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) {
String project_icon_path = GLOBAL_GET("application/config/icon");

Expand Down Expand Up @@ -1739,61 +1673,34 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &
}

void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
const String &processed_splash_config_xml,
const Ref<Image> &splash_image,
const Ref<Image> &splash_bg_color_image,
const Ref<Image> &main_image,
const Ref<Image> &foreground,
const Ref<Image> &background) {
const Ref<Image> &p_main_image,
const Ref<Image> &p_foreground,
const Ref<Image> &p_background) {
String gradle_build_dir = ExportTemplateManager::get_android_build_directory(p_preset);

// Store the splash configuration
if (!processed_splash_config_xml.is_empty()) {
print_verbose("Storing processed splash configuration: " + String("\n") + processed_splash_config_xml);
store_string_at_path(gradle_build_dir.path_join(SPLASH_CONFIG_PATH), processed_splash_config_xml);
}

// Store the splash image
if (splash_image.is_valid() && !splash_image->is_empty()) {
String splash_export_path = gradle_build_dir.path_join(SPLASH_IMAGE_EXPORT_PATH);
print_verbose("Storing splash image in " + splash_export_path);
Vector<uint8_t> data;
_load_image_data(splash_image, data);
store_file_at_path(splash_export_path, data);
}

// Store the splash bg color image
if (splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
String splash_bg_color_path = gradle_build_dir.path_join(SPLASH_BG_COLOR_PATH);
print_verbose("Storing splash background image in " + splash_bg_color_path);
Vector<uint8_t> data;
_load_image_data(splash_bg_color_image, data);
store_file_at_path(splash_bg_color_path, data);
}

// Prepare images to be resized for the icons. If some image ends up being uninitialized,
// the default image from the export template will be used.

for (int i = 0; i < icon_densities_count; ++i) {
if (main_image.is_valid() && !main_image->is_empty()) {
if (p_main_image.is_valid() && !p_main_image->is_empty()) {
print_verbose("Processing launcher icon for dimension " + itos(launcher_icons[i].dimensions) + " into " + launcher_icons[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data);
_process_launcher_icons(launcher_icons[i].export_path, p_main_image, launcher_icons[i].dimensions, data);
store_file_at_path(gradle_build_dir.path_join(launcher_icons[i].export_path), data);
}

if (foreground.is_valid() && !foreground->is_empty()) {
print_verbose("Processing launcher adaptive icon foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path);
if (p_foreground.is_valid() && !p_foreground->is_empty()) {
print_verbose("Processing launcher adaptive icon p_foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground,
_process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, p_foreground,
launcher_adaptive_icon_foregrounds[i].dimensions, data);
store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_foregrounds[i].export_path), data);
}

if (background.is_valid() && !background->is_empty()) {
print_verbose("Processing launcher adaptive icon background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path);
if (p_background.is_valid() && !p_background->is_empty()) {
print_verbose("Processing launcher adaptive icon p_background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background,
_process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, p_background,
launcher_adaptive_icon_backgrounds[i].dimensions, data);
store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_backgrounds[i].export_path), data);
}
Expand Down Expand Up @@ -3093,10 +3000,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("- include filter: " + p_preset->get_include_filter());
print_verbose("- exclude filter: " + p_preset->get_exclude_filter());

Ref<Image> splash_image;
Ref<Image> splash_bg_color_image;
String processed_splash_config_xml = load_splash_refs(splash_image, splash_bg_color_image);

Ref<Image> main_image;
Ref<Image> foreground;
Ref<Image> background;
Expand Down Expand Up @@ -3172,7 +3075,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res/*.xml files with project name."));
}
// Copies the project icon files into the appropriate Gradle project directory.
_copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background);
_copy_icons_to_gradle_project(p_preset, main_image, foreground, background);
// Write an AndroidManifest.xml file into the Gradle project directory.
_write_tmp_manifest(p_preset, p_give_internet, p_debug);

Expand Down Expand Up @@ -3486,16 +3389,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
_fix_resources(p_preset, data);
}

// Process the splash image
if ((file == SPLASH_IMAGE_EXPORT_PATH || file == LEGACY_BUILD_SPLASH_IMAGE_EXPORT_PATH) && splash_image.is_valid() && !splash_image->is_empty()) {
_load_image_data(splash_image, data);
}

// Process the splash bg color image
if ((file == SPLASH_BG_COLOR_PATH || file == LEGACY_BUILD_SPLASH_BG_COLOR_PATH) && splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
_load_image_data(splash_bg_color_image, data);
}

if (file.ends_with(".png") && file.contains("mipmap")) {
for (int i = 0; i < icon_densities_count; ++i) {
if (main_image.is_valid() && !main_image->is_empty()) {
Expand Down
23 changes: 3 additions & 20 deletions platform/android/export/export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,6 @@
#include "core/os/os.h"
#include "editor/export/editor_export_platform.h"

const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/splash_bg_color" />
<item>
<bitmap
android:gravity="center"
android:filter="%s"
android:src="@drawable/splash" />
</item>
</layer-list>
)SPLASH";

// Optional environment variables for defining confidential information. If any
// of these is set, they will override the values set in the credentials file.
const String ENV_ANDROID_KEYSTORE_DEBUG_PATH = "GODOT_ANDROID_KEYSTORE_DEBUG_PATH";
Expand Down Expand Up @@ -179,17 +167,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {

void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data);

String load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image);

void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background);

void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
const String &processed_splash_config_xml,
const Ref<Image> &splash_image,
const Ref<Image> &splash_bg_color_image,
const Ref<Image> &main_image,
const Ref<Image> &foreground,
const Ref<Image> &background);
const Ref<Image> &p_main_image,
const Ref<Image> &p_foreground,
const Ref<Image> &p_background);

static void _create_editor_debug_keystore_if_needed();

Expand Down
1 change: 1 addition & 0 deletions platform/android/java/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ configurations {

dependencies {
implementation "androidx.fragment:fragment:$versions.fragmentVersion"
implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion"

if (rootProject.findProject(":lib")) {
implementation project(":lib")
Expand Down
3 changes: 2 additions & 1 deletion platform/android/java/app/config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ ext.versions = [
nexusPublishVersion: '1.3.0',
javaVersion : JavaVersion.VERSION_17,
// Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
ndkVersion : '23.2.8568313'
ndkVersion : '23.2.8568313',
splashscreenVersion: '1.0.1'

]

Expand Down
Binary file not shown.
Binary file not shown.
12 changes: 0 additions & 12 deletions platform/android/java/app/res/drawable/splash_drawable.xml

This file was deleted.

15 changes: 12 additions & 3 deletions platform/android/java/app/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@

<style name="GodotAppMainTheme" parent="@android:style/Theme.Black.NoTitleBar"/>

<style name="GodotAppSplashTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<item name="android:windowBackground">@drawable/splash_drawable</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<style name="GodotAppSplashTheme" parent="Theme.SplashScreen">
<!-- Set the splash screen background, animated icon, and animation
duration. -->
<item name="android:windowSplashScreenBackground">@mipmap/icon_background</item>

<!-- Use windowSplashScreenAnimatedIcon to add a drawable or an animated
drawable. One of these is required. -->
<item name="windowSplashScreenAnimatedIcon">@mipmap/icon_foreground</item>

<!-- Set the theme of the Activity that directly follows your splash
screen. This is required. -->
<item name="postSplashScreenTheme">@style/GodotAppMainTheme</item>
</style>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@

import android.os.Bundle;

import androidx.core.splashscreen.SplashScreen;

/**
* Template activity for Godot Android builds.
* Feel free to extend and modify this class for your custom logic.
*/
public class GodotApp extends GodotActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.GodotAppMainTheme);
SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);
}
}
8 changes: 8 additions & 0 deletions platform/android/java/editor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ dependencies {
implementation project(":lib")

implementation "androidx.window:window:1.2.0"
implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
}

ext {
Expand Down Expand Up @@ -92,6 +94,10 @@ android {
targetSdkVersion versions.targetSdk

missingDimensionStrategy 'products', 'editor'
manifestPlaceholders += [
editorAppName: "Godot Editor 4",
editorBuildSuffix: ""
]
}

base {
Expand Down Expand Up @@ -124,11 +130,13 @@ android {
dev {
initWith debug
applicationIdSuffix ".dev"
manifestPlaceholders += [editorBuildSuffix: " (dev)"]
}

debug {
initWith release
applicationIdSuffix ".debug"
manifestPlaceholders += [editorBuildSuffix: " (debug)"]
signingConfig signingConfigs.debug
}

Expand Down

This file was deleted.

4 changes: 0 additions & 4 deletions platform/android/java/editor/src/dev/res/values/strings.xml

This file was deleted.

Loading
Loading