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

Re-architect how Android plugins are packaged and handled at export time #78958

Merged
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
75 changes: 75 additions & 0 deletions doc/classes/EditorExportPlugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
To use [EditorExportPlugin], register it using the [method EditorPlugin.add_export_plugin] method first.
</description>
<tutorials>
<link title="Export Android plugins">$DOCS_URL/tutorials/platform/android/android_plugin.html</link>
</tutorials>
<methods>
<method name="_begin_customize_resources" qualifiers="virtual const">
Expand Down Expand Up @@ -84,6 +85,64 @@
Calling [method skip] inside this callback will make the file not included in the export.
</description>
</method>
<method name="_get_android_dependencies" qualifiers="virtual const">
<return type="PackedStringArray" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="debug" type="bool" />
<description>
Virtual method to be overridden by the user. This is called to retrieve the set of Android dependencies provided by this plugin. Each returned Android dependency should have the format of an Android remote binary dependency: [code]org.godot.example:my-plugin:0.0.0[/code]
For more information see [url=https://developer.android.com/build/dependencies?agpversion=4.1#dependency-types]Android documentation on dependencies[/url].
[b]Note:[/b] Only supported on Android and requires [member EditorExportPlatformAndroid.gradle_build/use_gradle_build] to be enabled.
</description>
</method>
<method name="_get_android_dependencies_maven_repos" qualifiers="virtual const">
<return type="PackedStringArray" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="debug" type="bool" />
<description>
Virtual method to be overridden by the user. This is called to retrieve the URLs of Maven repositories for the set of Android dependencies provided by this plugin.
For more information see [url=https://docs.gradle.org/current/userguide/dependency_management.html#sec:maven_repo]Gradle documentation on dependency management[/url].
[b]Note:[/b] Google's Maven repo and the Maven Central repo are already included by default.
[b]Note:[/b] Only supported on Android and requires [member EditorExportPlatformAndroid.gradle_build/use_gradle_build] to be enabled.
</description>
</method>
<method name="_get_android_libraries" qualifiers="virtual const">
<return type="PackedStringArray" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="debug" type="bool" />
<description>
Virtual method to be overridden by the user. This is called to retrieve the local paths of the Android libraries archive (AAR) files provided by this plugin.
[b]Note:[/b] Relative paths **must** be relative to Godot's [code]res://addons/[/code] directory. For example, an AAR file located under [code]res://addons/hello_world_plugin/HelloWorld.release.aar[/code] can be returned as an absolute path using [code]res://addons/hello_world_plugin/HelloWorld.release.aar[/code] or a relative path using [code]hello_world_plugin/HelloWorld.release.aar[/code].
[b]Note:[/b] Only supported on Android and requires [member EditorExportPlatformAndroid.gradle_build/use_gradle_build] to be enabled.
</description>
</method>
<method name="_get_android_manifest_activity_element_contents" qualifiers="virtual const">
<return type="String" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="debug" type="bool" />
<description>
Virtual method to be overridden by the user. This is used at export time to update the contents of the [code]activity[/code] element in the generated Android manifest.
[b]Note:[/b] Only supported on Android and requires [member EditorExportPlatformAndroid.gradle_build/use_gradle_build] to be enabled.
</description>
</method>
<method name="_get_android_manifest_application_element_contents" qualifiers="virtual const">
<return type="String" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="debug" type="bool" />
<description>
Virtual method to be overridden by the user. This is used at export time to update the contents of the [code]application[/code] element in the generated Android manifest.
[b]Note:[/b] Only supported on Android and requires [member EditorExportPlatformAndroid.gradle_build/use_gradle_build] to be enabled.
</description>
</method>
<method name="_get_android_manifest_element_contents" qualifiers="virtual const">
<return type="String" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="debug" type="bool" />
<description>
Virtual method to be overridden by the user. This is used at export time to update the contents of the [code]manifest[/code] element in the generated Android manifest.
[b]Note:[/b] Only supported on Android and requires [member EditorExportPlatformAndroid.gradle_build/use_gradle_build] to be enabled.
</description>
</method>
<method name="_get_customization_configuration_hash" qualifiers="virtual const">
<return type="int" />
<description>
Expand All @@ -99,6 +158,15 @@
Return a [PackedStringArray] of additional features this preset, for the given [param platform], should have.
</description>
</method>
<method name="_get_export_option_warning" qualifiers="virtual const">
<return type="String" />
<param index="0" name="platform" type="EditorExportPlatform" />
<param index="1" name="option" type="String" />
<description>
Check the requirements for the given [param option] and return a non-empty warning string if they are not met.
[b]Note:[/b] Use [method get_option] to check the value of the export options.
</description>
</method>
<method name="_get_export_options" qualifiers="virtual const">
<return type="Dictionary[]" />
<param index="0" name="platform" type="EditorExportPlatform" />
Expand All @@ -124,6 +192,13 @@
Return [code]true[/code], if the result of [method _get_export_options] has changed and the export options of preset corresponding to [param platform] should be updated.
</description>
</method>
<method name="_supports_platform" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="platform" type="EditorExportPlatform" />
<description>
Return [code]true[/code] if the plugin supports the given [param platform].
</description>
</method>
<method name="add_file">
<return type="void" />
<param index="0" name="path" type="String" />
Expand Down
6 changes: 6 additions & 0 deletions doc/classes/EditorPlugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,12 @@
Returns the [PopupMenu] under [b]Scene &gt; Export As...[/b].
</description>
</method>
<method name="get_plugin_version" qualifiers="const">
<return type="String" />
<description>
Provide the version of the plugin declared in the [code]plugin.cfg[/code] config file.
</description>
</method>
<method name="get_script_create_dialog">
<return type="ScriptCreateDialog" />
<description>
Expand Down
6 changes: 6 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3363,6 +3363,11 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
return;
}

String plugin_version;
if (cf->has_section_key("plugin", "version")) {
plugin_version = cf->get_value("plugin", "version");
}

if (!cf->has_section_key("plugin", "script")) {
show_warning(vformat(TTR("Unable to find script field for addon plugin at: '%s'."), addon_path));
return;
Expand Down Expand Up @@ -3408,6 +3413,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,

EditorPlugin *ep = memnew(EditorPlugin);
ep->set_script(scr);
ep->set_plugin_version(plugin_version);
addon_name_to_plugin[addon_path] = ep;
add_editor_plugin(ep, p_config_changed);

Expand Down
9 changes: 9 additions & 0 deletions editor/editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ const Ref<Texture2D> EditorPlugin::get_icon() const {
return icon;
}

String EditorPlugin::get_plugin_version() const {
return plugin_version;
}

void EditorPlugin::set_plugin_version(const String &p_version) {
plugin_version = p_version;
}

bool EditorPlugin::has_main_screen() const {
bool success = false;
GDVIRTUAL_CALL(_has_main_screen, success);
Expand Down Expand Up @@ -583,6 +591,7 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_script_create_dialog"), &EditorPlugin::get_script_create_dialog);
ClassDB::bind_method(D_METHOD("add_debugger_plugin", "script"), &EditorPlugin::add_debugger_plugin);
ClassDB::bind_method(D_METHOD("remove_debugger_plugin", "script"), &EditorPlugin::remove_debugger_plugin);
ClassDB::bind_method(D_METHOD("get_plugin_version"), &EditorPlugin::get_plugin_version);

GDVIRTUAL_BIND(_forward_canvas_gui_input, "event");
GDVIRTUAL_BIND(_forward_canvas_draw_over_viewport, "viewport_control");
Expand Down
3 changes: 3 additions & 0 deletions editor/editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class EditorPlugin : public Node {
bool force_draw_over_forwarding_enabled = false;

String last_main_screen_name;
String plugin_version;

void _editor_project_settings_changed();

Expand Down Expand Up @@ -168,6 +169,8 @@ class EditorPlugin : public Node {

virtual String get_name() const;
virtual const Ref<Texture2D> get_icon() const;
virtual String get_plugin_version() const;
virtual void set_plugin_version(const String &p_version);
virtual bool has_main_screen() const;
virtual void make_visible(bool p_visible);
virtual void selected_notify() {} //notify that it was raised by the user, not the editor
Expand Down
24 changes: 21 additions & 3 deletions editor/export/editor_export_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &

struct SortByName {
bool operator()(const Ref<EditorExportPlugin> &left, const Ref<EditorExportPlugin> &right) const {
return left->_get_name() < right->_get_name();
return left->get_name() < right->get_name();
}
};

Expand Down Expand Up @@ -1033,14 +1033,14 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
if (export_plugins.write[i]->_begin_customize_resources(Ref<EditorExportPlatform>(this), features_psa)) {
customize_resources_plugins.push_back(export_plugins[i]);

custom_resources_hash = hash_murmur3_one_64(export_plugins[i]->_get_name().hash64(), custom_resources_hash);
custom_resources_hash = hash_murmur3_one_64(export_plugins[i]->get_name().hash64(), custom_resources_hash);
uint64_t hash = export_plugins[i]->_get_customization_configuration_hash();
custom_resources_hash = hash_murmur3_one_64(hash, custom_resources_hash);
}
if (export_plugins.write[i]->_begin_customize_scenes(Ref<EditorExportPlatform>(this), features_psa)) {
customize_scenes_plugins.push_back(export_plugins[i]);

custom_resources_hash = hash_murmur3_one_64(export_plugins[i]->_get_name().hash64(), custom_resources_hash);
custom_resources_hash = hash_murmur3_one_64(export_plugins[i]->get_name().hash64(), custom_resources_hash);
uint64_t hash = export_plugins[i]->_get_customization_configuration_hash();
custom_scene_hash = hash_murmur3_one_64(hash, custom_scene_hash);
}
Expand Down Expand Up @@ -1800,6 +1800,24 @@ bool EditorExportPlatform::can_export(const Ref<EditorExportPreset> &p_preset, S
if (!templates_error.is_empty()) {
r_error += templates_error;
}

String export_plugins_warning;
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
Ref<EditorExportPlatform> export_platform = Ref<EditorExportPlatform>(this);
if (!export_plugins[i]->supports_platform(export_platform)) {
continue;
}

String plugin_warning = export_plugins.write[i]->_has_valid_export_configuration(export_platform, p_preset);
if (!plugin_warning.is_empty()) {
export_plugins_warning += plugin_warning;
}
}

if (!export_plugins_warning.is_empty()) {
r_error += export_plugins_warning;
}
#endif

String project_configuration_error;
Expand Down
81 changes: 80 additions & 1 deletion editor/export/editor_export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,27 @@ Variant EditorExportPlugin::get_option(const StringName &p_name) const {
return export_preset->get(p_name);
}

String EditorExportPlugin::_has_valid_export_configuration(const Ref<EditorExportPlatform> &p_export_platform, const Ref<EditorExportPreset> &p_preset) {
String warning;
if (!supports_platform(p_export_platform)) {
warning += vformat(TTR("Plugin \"%s\" is not supported on \"%s\""), get_name(), p_export_platform->get_name());
warning += "\n";
return warning;
}

set_export_preset(p_preset);
List<EditorExportPlatform::ExportOption> options;
_get_export_options(p_export_platform, &options);
for (const EditorExportPlatform::ExportOption &E : options) {
String option_warning = _get_export_option_warning(p_export_platform, E.option.name);
if (!option_warning.is_empty()) {
warning += option_warning + "\n";
}
}

return warning;
}

void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) {
GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features);
}
Expand Down Expand Up @@ -184,12 +205,54 @@ void EditorExportPlugin::_end_customize_resources() {
GDVIRTUAL_CALL(_end_customize_resources);
}

String EditorExportPlugin::_get_name() const {
String EditorExportPlugin::get_name() const {
String ret;
GDVIRTUAL_REQUIRED_CALL(_get_name, ret);
return ret;
}

bool EditorExportPlugin::supports_platform(const Ref<EditorExportPlatform> &p_export_platform) const {
bool ret = false;
GDVIRTUAL_CALL(_supports_platform, p_export_platform, ret);
return ret;
}

PackedStringArray EditorExportPlugin::get_android_dependencies(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
PackedStringArray ret;
GDVIRTUAL_CALL(_get_android_dependencies, p_export_platform, p_debug, ret);
return ret;
}

PackedStringArray EditorExportPlugin::get_android_dependencies_maven_repos(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
PackedStringArray ret;
GDVIRTUAL_CALL(_get_android_dependencies_maven_repos, p_export_platform, p_debug, ret);
return ret;
}

PackedStringArray EditorExportPlugin::get_android_libraries(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
PackedStringArray ret;
GDVIRTUAL_CALL(_get_android_libraries, p_export_platform, p_debug, ret);
return ret;
}

String EditorExportPlugin::get_android_manifest_activity_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
String ret;
GDVIRTUAL_CALL(_get_android_manifest_activity_element_contents, p_export_platform, p_debug, ret);
return ret;
}

String EditorExportPlugin::get_android_manifest_application_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
String ret;
GDVIRTUAL_CALL(_get_android_manifest_application_element_contents, p_export_platform, p_debug, ret);
return ret;
}

String EditorExportPlugin::get_android_manifest_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const {
String ret;
GDVIRTUAL_CALL(_get_android_manifest_element_contents, p_export_platform, p_debug, ret);
return ret;
}

PackedStringArray EditorExportPlugin::_get_export_features(const Ref<EditorExportPlatform> &p_platform, bool p_debug) const {
PackedStringArray ret;
GDVIRTUAL_CALL(_get_export_features, p_platform, p_debug, ret);
Expand All @@ -216,6 +279,12 @@ bool EditorExportPlugin::_should_update_export_options(const Ref<EditorExportPla
return ret;
}

String EditorExportPlugin::_get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const {
String ret;
GDVIRTUAL_CALL(_get_export_option_warning, p_export_platform, p_option_name, ret);
return ret;
}

void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) {
}

Expand Down Expand Up @@ -257,9 +326,19 @@ void EditorExportPlugin::_bind_methods() {

GDVIRTUAL_BIND(_get_export_options, "platform");
GDVIRTUAL_BIND(_should_update_export_options, "platform");
GDVIRTUAL_BIND(_get_export_option_warning, "platform", "option");

GDVIRTUAL_BIND(_get_export_features, "platform", "debug");
GDVIRTUAL_BIND(_get_name);

GDVIRTUAL_BIND(_supports_platform, "platform");

GDVIRTUAL_BIND(_get_android_dependencies, "platform", "debug");
GDVIRTUAL_BIND(_get_android_dependencies_maven_repos, "platform", "debug");
GDVIRTUAL_BIND(_get_android_libraries, "platform", "debug");
GDVIRTUAL_BIND(_get_android_manifest_activity_element_contents, "platform", "debug");
GDVIRTUAL_BIND(_get_android_manifest_application_element_contents, "platform", "debug");
GDVIRTUAL_BIND(_get_android_manifest_element_contents, "platform", "debug");
}

EditorExportPlugin::EditorExportPlugin() {
Expand Down
Loading
Loading