Make use of activity-alias as the launcher mechanism for the Godot editor and the Godot app template

This commit is contained in:
Fredia Huya-Kouadio 2025-11-06 11:30:07 -08:00
parent e47fb8b898
commit 2ed51e00a1
14 changed files with 391 additions and 81 deletions

View file

@ -31,6 +31,7 @@
#include "gradle_export_util.h"
#include "core/string/translation_server.h"
#include "modules/regex/regex.h"
int _get_android_orientation_value(DisplayServer::ScreenOrientation screen_orientation) {
switch (screen_orientation) {
@ -284,6 +285,19 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) {
}
String _get_activity_tag(const Ref<EditorExportPlatform> &p_export_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug) {
String export_plugins_activity_element_contents;
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->supports_platform(p_export_platform)) {
const String contents = export_plugins[i]->get_android_manifest_activity_element_contents(p_export_platform, p_debug);
if (!contents.is_empty()) {
export_plugins_activity_element_contents += contents;
export_plugins_activity_element_contents += "\n";
}
}
}
// Update the GodotApp activity tag.
String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(p_export_platform->get_project_setting(p_preset, "display/window/handheld/orientation"))));
String manifest_activity_text = vformat(
" <activity android:name=\".GodotApp\" "
@ -296,6 +310,20 @@ String _get_activity_tag(const Ref<EditorExportPlatform> &p_export_platform, con
orientation,
bool_to_string(bool(p_export_platform->get_project_setting(p_preset, "display/window/size/resizable"))));
// *LAUNCHER and *HOME categories should only go to the activity-alias.
Ref<RegEx> activity_content_to_remove_regex = RegEx::create_from_string(R"delim(<category\s+android:name\s*=\s*"\S+(LAUNCHER|HOME)"\s*\/>)delim");
String updated_export_plugins_activity_element_contents = activity_content_to_remove_regex->sub(export_plugins_activity_element_contents, "", true);
manifest_activity_text += updated_export_plugins_activity_element_contents;
manifest_activity_text += " </activity>\n";
// Update the GodotAppLauncher activity tag.
manifest_activity_text += " <activity-alias\n"
" tools:node=\"mergeOnlyAttributes\"\n"
" android:name=\".GodotAppLauncher\"\n"
" android:targetActivity=\".GodotApp\"\n"
" android:exported=\"true\">\n";
manifest_activity_text += " <intent-filter>\n"
" <action android:name=\"android.intent.action.MAIN\" />\n"
" <category android:name=\"android.intent.category.DEFAULT\" />\n";
@ -317,18 +345,12 @@ String _get_activity_tag(const Ref<EditorExportPlatform> &p_export_platform, con
manifest_activity_text += " </intent-filter>\n";
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->supports_platform(p_export_platform)) {
const String contents = export_plugins[i]->get_android_manifest_activity_element_contents(p_export_platform, p_debug);
if (!contents.is_empty()) {
manifest_activity_text += contents;
manifest_activity_text += "\n";
}
}
}
// Hybrid categories should only go to the actual 'GodotApp' activity.
Ref<RegEx> activity_alias_content_to_remove_regex = RegEx::create_from_string(R"delim(<category\s+android:name\s*=\s*"org.godotengine.xr.hybrid.(IMMERSIVE|PANEL)"\s*\/>)delim");
String updated_export_plugins_activity_alias_element_contents = activity_alias_content_to_remove_regex->sub(export_plugins_activity_element_contents, "", true);
manifest_activity_text += updated_export_plugins_activity_alias_element_contents;
manifest_activity_text += " </activity>\n";
manifest_activity_text += " </activity-alias>\n";
return manifest_activity_text;
}