Automatically generate the Android debug keystore

Automatically generate the Android debug keystore when the Java SDK path is specified.
This commit is contained in:
Fredia Huya-Kouadio 2024-04-12 23:53:28 -07:00
parent 029aadef56
commit a8c9b59f3f
6 changed files with 105 additions and 7 deletions

View File

@ -70,6 +70,10 @@ String EditorPaths::get_export_templates_dir() const {
return get_data_dir().path_join(export_templates_folder);
}
String EditorPaths::get_debug_keystore_path() const {
return get_data_dir().path_join("keystores/debug.keystore");
}
String EditorPaths::get_project_settings_dir() const {
return get_project_data_dir().path_join("editor");
}

View File

@ -63,6 +63,7 @@ public:
String get_cache_dir() const;
String get_project_data_dir() const;
String get_export_templates_dir() const;
String get_debug_keystore_path() const;
String get_project_settings_dir() const;
String get_text_editor_themes_dir() const;
String get_script_templates_dir() const;

View File

@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/io/config_file.h"
#include "editor/editor_settings.h"
EditorExport *EditorExport::singleton = nullptr;
@ -191,6 +192,12 @@ void EditorExport::_notification(int p_what) {
export_platforms.write[i]->cleanup();
}
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
for (int i = 0; i < export_platforms.size(); i++) {
export_platforms.write[i]->notification(p_what);
}
} break;
}
}

View File

@ -33,6 +33,7 @@
#include "export_plugin.h"
#include "core/os/os.h"
#include "editor/editor_paths.h"
#include "editor/editor_settings.h"
#include "editor/export/editor_export.h"
@ -46,10 +47,10 @@ void register_android_exporter() {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/java_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
EDITOR_DEF("export/android/android_sdk_path", OS::get_singleton()->get_environment("ANDROID_HOME"));
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/android_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
EDITOR_DEF("export/android/debug_keystore", "");
EDITOR_DEF("export/android/debug_keystore", EditorPaths::get_singleton()->get_debug_keystore_path());
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/debug_keystore_user", DEFAULT_ANDROID_KEYSTORE_DEBUG_USER);
EDITOR_DEF("export/android/debug_keystore_pass", DEFAULT_ANDROID_KEYSTORE_DEBUG_PASSWORD);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore_pass", PROPERTY_HINT_PASSWORD));
EDITOR_DEF("export/android/force_system_user", false);

View File

@ -831,14 +831,82 @@ bool EditorExportPlatformAndroid::_uses_vulkan() {
void EditorExportPlatformAndroid::_notification(int p_what) {
#ifndef ANDROID_ENABLED
if (p_what == NOTIFICATION_POSTINITIALIZE) {
if (EditorExport::get_singleton()) {
EditorExport::get_singleton()->connect_presets_runnable_updated(callable_mp(this, &EditorExportPlatformAndroid::_update_preset_status));
}
switch (p_what) {
case NOTIFICATION_POSTINITIALIZE: {
if (EditorExport::get_singleton()) {
EditorExport::get_singleton()->connect_presets_runnable_updated(callable_mp(this, &EditorExportPlatformAndroid::_update_preset_status));
}
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (EditorSettings::get_singleton()->check_changed_settings_in_group("export/android")) {
_create_editor_debug_keystore_if_needed();
}
} break;
}
#endif
}
void EditorExportPlatformAndroid::_create_editor_debug_keystore_if_needed() {
// Check if we have a valid keytool path.
String keytool_path = get_keytool_path();
if (!FileAccess::exists(keytool_path)) {
return;
}
// Check if the current editor debug keystore exists.
String editor_debug_keystore = EDITOR_GET("export/android/debug_keystore");
if (FileAccess::exists(editor_debug_keystore)) {
return;
}
// Generate the debug keystore.
String keystore_path = EditorPaths::get_singleton()->get_debug_keystore_path();
String keystores_dir = keystore_path.get_base_dir();
if (!DirAccess::exists(keystores_dir)) {
Ref<DirAccess> dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = dir_access->make_dir_recursive(keystores_dir);
if (err != OK) {
WARN_PRINT(TTR("Error creating keystores directory:") + "\n" + keystores_dir);
return;
}
}
if (!FileAccess::exists(keystore_path)) {
String output;
List<String> args;
args.push_back("-genkey");
args.push_back("-keystore");
args.push_back(keystore_path);
args.push_back("-storepass");
args.push_back("android");
args.push_back("-alias");
args.push_back(DEFAULT_ANDROID_KEYSTORE_DEBUG_USER);
args.push_back("-keypass");
args.push_back(DEFAULT_ANDROID_KEYSTORE_DEBUG_PASSWORD);
args.push_back("-keyalg");
args.push_back("RSA");
args.push_back("-keysize");
args.push_back("2048");
args.push_back("-validity");
args.push_back("10000");
args.push_back("-dname");
args.push_back("cn=Godot, ou=Godot Engine, o=Stichting Godot, c=NL");
Error error = OS::get_singleton()->execute(keytool_path, args, &output, nullptr, true);
print_verbose(output);
if (error != OK) {
WARN_PRINT("Error: Unable to create debug keystore");
return;
}
}
// Update the editor settings.
EditorSettings::get_singleton()->set("export/android/debug_keystore", keystore_path);
EditorSettings::get_singleton()->set("export/android/debug_keystore_user", DEFAULT_ANDROID_KEYSTORE_DEBUG_USER);
EditorSettings::get_singleton()->set("export/android/debug_keystore_pass", DEFAULT_ANDROID_KEYSTORE_DEBUG_PASSWORD);
print_verbose("Updated editor debug keystore to " + keystore_path);
}
void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions) {
const char **aperms = android_perms;
while (*aperms) {
@ -2202,6 +2270,15 @@ String EditorExportPlatformAndroid::get_java_path() {
return java_sdk_path.path_join("bin/java" + exe_ext);
}
String EditorExportPlatformAndroid::get_keytool_path() {
String exe_ext;
if (OS::get_singleton()->get_name() == "Windows") {
exe_ext = ".exe";
}
String java_sdk_path = EDITOR_GET("export/android/java_sdk_path");
return java_sdk_path.path_join("bin/keytool" + exe_ext);
}
String EditorExportPlatformAndroid::get_adb_path() {
String exe_ext;
if (OS::get_singleton()->get_name() == "Windows") {
@ -3647,6 +3724,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
android_plugins_changed.set();
#endif // DISABLE_DEPRECATED
#ifndef ANDROID_ENABLED
_create_editor_debug_keystore_if_needed();
_update_preset_status();
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
#endif

View File

@ -60,6 +60,9 @@ const String ENV_ANDROID_KEYSTORE_RELEASE_PATH = "GODOT_ANDROID_KEYSTORE_RELEASE
const String ENV_ANDROID_KEYSTORE_RELEASE_USER = "GODOT_ANDROID_KEYSTORE_RELEASE_USER";
const String ENV_ANDROID_KEYSTORE_RELEASE_PASS = "GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD";
const String DEFAULT_ANDROID_KEYSTORE_DEBUG_USER = "androiddebugkey";
const String DEFAULT_ANDROID_KEYSTORE_DEBUG_PASSWORD = "android";
struct LauncherIcon {
const char *export_path;
int dimensions = 0;
@ -186,6 +189,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
const Ref<Image> &foreground,
const Ref<Image> &background);
static void _create_editor_debug_keystore_if_needed();
static Vector<ABI> get_enabled_abis(const Ref<EditorExportPreset> &p_preset);
static bool _uses_vulkan();
@ -234,6 +239,8 @@ public:
static String get_java_path();
static String get_keytool_path();
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;
static bool has_valid_username_and_password(const Ref<EditorExportPreset> &p_preset, String &r_error);