Browse Source

Merge pull request #62602 from akien-mga/3.x-android-preset-refactor-custom-build

Rémi Verschelde 3 years ago
parent
commit
bcd5a6951d
2 changed files with 68 additions and 28 deletions
  1. 2 0
      editor/editor_node.cpp
  2. 66 28
      platform/android/export/export_plugin.cpp

+ 2 - 0
editor/editor_node.cpp

@@ -7126,6 +7126,8 @@ EditorNode::EditorNode() {
 	execute_output_dialog = memnew(AcceptDialog);
 	execute_output_dialog = memnew(AcceptDialog);
 	execute_output_dialog->add_child(execute_outputs);
 	execute_output_dialog->add_child(execute_outputs);
 	execute_output_dialog->set_title("");
 	execute_output_dialog->set_title("");
+	// Prevent closing too fast and missing important information.
+	execute_output_dialog->set_exclusive(true);
 	gui_base->add_child(execute_output_dialog);
 	gui_base->add_child(execute_output_dialog);
 
 
 	EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed");
 	EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed");

+ 66 - 28
platform/android/export/export_plugin.cpp

@@ -227,7 +227,6 @@ static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/instal
 
 
 static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
 static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
 static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
 static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
-const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION);
 
 
 void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
 void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
 	EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
 	EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
@@ -1691,8 +1690,13 @@ void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPres
 void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_options) {
 void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_options) {
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
-	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
-	r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
+
+	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_build/use_custom_build"), false));
+	r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_build/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
+	// Using String instead of int to default to an empty string (no override) with placeholder for instructions (see GH-62465).
+	// This implies doing validation that the string is a proper int.
+	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_MIN_SDK_VERSION)), ""));
+	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_build/target_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_TARGET_SDK_VERSION)), ""));
 
 
 	Vector<PluginConfigAndroid> plugins_configs = get_plugins();
 	Vector<PluginConfigAndroid> plugins_configs = get_plugins();
 	for (int i = 0; i < plugins_configs.size(); i++) {
 	for (int i = 0; i < plugins_configs.size(); i++) {
@@ -1719,8 +1723,6 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
 
 
 	r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
-	r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/min_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_MIN_SDK_VERSION));
-	r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/target_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_TARGET_SDK_VERSION));
 
 
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
@@ -2056,7 +2058,7 @@ String EditorExportPlatformAndroid::get_apksigner_path() {
 bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
 bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
 	String err;
 	String err;
 	bool valid = false;
 	bool valid = false;
-	const bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
+	const bool custom_build_enabled = p_preset->get("custom_build/use_custom_build");
 
 
 	// Look for export templates (first official, and if defined custom templates).
 	// Look for export templates (first official, and if defined custom templates).
 
 
@@ -2230,7 +2232,7 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
 	if (xr_mode_index != XR_MODE_OVR && xr_mode_index != XR_MODE_OPENXR) {
 	if (xr_mode_index != XR_MODE_OVR && xr_mode_index != XR_MODE_OPENXR) {
 		if (hand_tracking > XR_HAND_TRACKING_NONE) {
 		if (hand_tracking > XR_HAND_TRACKING_NONE) {
 			valid = false;
 			valid = false;
-			err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" or \"OpenXR\".");
+			err += TTR("\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" or \"OpenXR\".");
 			err += "\n";
 			err += "\n";
 		}
 		}
 	}
 	}
@@ -2238,37 +2240,67 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
 	if (xr_mode_index != XR_MODE_OPENXR) {
 	if (xr_mode_index != XR_MODE_OPENXR) {
 		if (passthrough_mode > XR_PASSTHROUGH_NONE) {
 		if (passthrough_mode > XR_PASSTHROUGH_NONE) {
 			valid = false;
 			valid = false;
-			err += TTR("\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\".");
+			err += TTR("\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\".");
 			err += "\n";
 			err += "\n";
 		}
 		}
 	}
 	}
 
 
-	if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB &&
+	if (int(p_preset->get("custom_build/export_format")) == EXPORT_FORMAT_AAB &&
 			!custom_build_enabled) {
 			!custom_build_enabled) {
 		valid = false;
 		valid = false;
 		err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
 		err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
 		err += "\n";
 		err += "\n";
 	}
 	}
 
 
-	// Check the min sdk version
-	int min_sdk_version = p_preset->get("version/min_sdk");
-	if (min_sdk_version != DEFAULT_MIN_SDK_VERSION && !custom_build_enabled) {
-		valid = false;
-		err += TTR("Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled.");
-		err += "\n";
+	// Check the min sdk version.
+	String min_sdk_str = p_preset->get("custom_build/min_sdk");
+	int min_sdk_int = DEFAULT_MIN_SDK_VERSION;
+	if (!min_sdk_str.empty()) { // Empty means no override, nothing to do.
+		if (!custom_build_enabled) {
+			valid = false;
+			err += TTR("\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled.");
+			err += "\n";
+		}
+		if (!min_sdk_str.is_valid_integer()) {
+			valid = false;
+			err += vformat(TTR("\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."), min_sdk_str);
+			err += "\n";
+		} else {
+			min_sdk_int = min_sdk_str.to_int();
+			if (min_sdk_int < DEFAULT_MIN_SDK_VERSION) {
+				valid = false;
+				err += vformat(TTR("\"Min SDK\" cannot be lower than %d, which is the version needed by the Godot library."), DEFAULT_MIN_SDK_VERSION);
+				err += "\n";
+			}
+		}
 	}
 	}
 
 
-	// Check the target sdk version
-	int target_sdk_version = p_preset->get("version/target_sdk");
-	if (target_sdk_version != DEFAULT_TARGET_SDK_VERSION && !custom_build_enabled) {
-		valid = false;
-		err += TTR("Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is enabled.");
-		err += "\n";
+	// Check the target sdk version.
+	String target_sdk_str = p_preset->get("custom_build/target_sdk");
+	int target_sdk_int = DEFAULT_TARGET_SDK_VERSION;
+	if (!target_sdk_str.empty()) { // Empty means no override, nothing to do.
+		if (!custom_build_enabled) {
+			valid = false;
+			err += TTR("\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled.");
+			err += "\n";
+		}
+		if (!target_sdk_str.is_valid_integer()) {
+			valid = false;
+			err += vformat(TTR("\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."), target_sdk_str);
+			err += "\n";
+		} else {
+			target_sdk_int = target_sdk_str.to_int();
+			if (target_sdk_int > DEFAULT_TARGET_SDK_VERSION) {
+				// Warning only, so don't override `valid`.
+				err += vformat(TTR("\"Target SDK\" %d is higher than the default version %d. This may work, but wasn't tested and may be unstable."), target_sdk_int, DEFAULT_TARGET_SDK_VERSION);
+				err += "\n";
+			}
+		}
 	}
 	}
 
 
-	if (target_sdk_version < min_sdk_version) {
+	if (target_sdk_int < min_sdk_int) {
 		valid = false;
 		valid = false;
-		err += TTR("\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version.");
+		err += TTR("\"Target SDK\" version must be greater or equal to \"Min SDK\" version.");
 		err += "\n";
 		err += "\n";
 	}
 	}
 
 
@@ -2639,7 +2671,7 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
 }
 }
 
 
 Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
 Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
-	int export_format = int(p_preset->get("custom_template/export_format"));
+	int export_format = int(p_preset->get("custom_build/export_format"));
 	String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
 	String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
 	String release_keystore = p_preset->get("keystore/release");
 	String release_keystore = p_preset->get("keystore/release");
 	String release_username = p_preset->get("keystore/release_user");
 	String release_username = p_preset->get("keystore/release_user");
@@ -2797,7 +2829,7 @@ String EditorExportPlatformAndroid::join_list(List<String> parts, const String &
 }
 }
 
 
 Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
 Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
-	int export_format = int(p_preset->get("custom_template/export_format"));
+	int export_format = int(p_preset->get("custom_build/export_format"));
 	bool should_sign = p_preset->get("package/signed");
 	bool should_sign = p_preset->get("package/signed");
 	return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
 	return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
 }
 }
@@ -2810,7 +2842,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 
 
 	EditorProgress ep("export", TTR("Exporting for Android"), 105, true);
 	EditorProgress ep("export", TTR("Exporting for Android"), 105, true);
 
 
-	bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
+	bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build"));
 	bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
 	bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
 	bool apk_expansion = p_preset->get("apk_expansion/enable");
 	bool apk_expansion = p_preset->get("apk_expansion/enable");
 	Vector<String> enabled_abis = get_enabled_abis(p_preset);
 	Vector<String> enabled_abis = get_enabled_abis(p_preset);
@@ -2939,8 +2971,14 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 		String package_name = get_package_name(p_preset->get("package/unique_name"));
 		String package_name = get_package_name(p_preset->get("package/unique_name"));
 		String version_code = itos(p_preset->get("version/code"));
 		String version_code = itos(p_preset->get("version/code"));
 		String version_name = p_preset->get("version/name");
 		String version_name = p_preset->get("version/name");
-		String min_sdk_version = itos(p_preset->get("version/min_sdk"));
-		String target_sdk_version = itos(p_preset->get("version/target_sdk"));
+		String min_sdk_version = p_preset->get("custom_build/min_sdk");
+		if (!min_sdk_version.is_valid_integer()) {
+			min_sdk_version = itos(DEFAULT_MIN_SDK_VERSION);
+		}
+		String target_sdk_version = p_preset->get("custom_build/target_sdk");
+		if (!target_sdk_version.is_valid_integer()) {
+			target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
+		}
 		String enabled_abi_string = String("|").join(enabled_abis);
 		String enabled_abi_string = String("|").join(enabled_abis);
 		String sign_flag = should_sign ? "true" : "false";
 		String sign_flag = should_sign ? "true" : "false";
 		String zipalign_flag = "true";
 		String zipalign_flag = "true";