You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-12 13:20:55 +00:00
Re-architecture of the Godot Android plugin.
This commit is contained in:
@@ -688,6 +688,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||
|
||||
int xr_mode_index = p_preset->get("xr_features/xr_mode");
|
||||
|
||||
String plugins = p_preset->get("custom_template/plugins");
|
||||
|
||||
Vector<String> perms;
|
||||
|
||||
const char **aperms = android_perms;
|
||||
@@ -851,6 +853,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
if (tname == "meta-data" && attrname == "value" && value == "custom_template_plugins_value") {
|
||||
// Update the meta-data 'android:value' attribute with the list of enabled plugins.
|
||||
string_table.write[attr_value] = plugins;
|
||||
}
|
||||
|
||||
iofs += 20;
|
||||
}
|
||||
|
||||
@@ -1363,6 +1370,7 @@ public:
|
||||
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::BOOL, "custom_template/use_custom_build"), false));
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/plugins", PROPERTY_HINT_PLACEHOLDER_TEXT, "Plugin1,Plugin2,..."), ""));
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
|
||||
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"));
|
||||
@@ -1743,260 +1751,6 @@ public:
|
||||
return list;
|
||||
}
|
||||
|
||||
void _update_custom_build_project() {
|
||||
|
||||
DirAccessRef da = DirAccess::open("res://android");
|
||||
|
||||
ERR_FAIL_COND_MSG(!da, "Cannot open directory 'res://android'.");
|
||||
Map<String, List<String> > directory_paths;
|
||||
Map<String, List<String> > manifest_sections;
|
||||
Map<String, List<String> > gradle_sections;
|
||||
da->list_dir_begin();
|
||||
String d = da->get_next();
|
||||
while (d != String()) {
|
||||
|
||||
if (!d.begins_with(".") && d != "build" && da->current_is_dir()) { //a dir and not the build dir
|
||||
//add directories found
|
||||
DirAccessRef ds = DirAccess::open(String("res://android").plus_file(d));
|
||||
if (ds) {
|
||||
ds->list_dir_begin();
|
||||
String sd = ds->get_next();
|
||||
while (sd != String()) {
|
||||
|
||||
if (!sd.begins_with(".") && ds->current_is_dir()) {
|
||||
String key = sd.to_upper();
|
||||
if (!directory_paths.has(key)) {
|
||||
directory_paths[key] = List<String>();
|
||||
}
|
||||
String path = ProjectSettings::get_singleton()->get_resource_path().plus_file("android").plus_file(d).plus_file(sd);
|
||||
directory_paths[key].push_back(path);
|
||||
print_line("Add: " + sd + ":" + path);
|
||||
}
|
||||
|
||||
sd = ds->get_next();
|
||||
}
|
||||
ds->list_dir_end();
|
||||
}
|
||||
//parse manifest
|
||||
{
|
||||
FileAccessRef f = FileAccess::open(String("res://android").plus_file(d).plus_file("AndroidManifest.conf"), FileAccess::READ);
|
||||
if (f) {
|
||||
|
||||
String section;
|
||||
while (!f->eof_reached()) {
|
||||
String l = f->get_line();
|
||||
String k = l.strip_edges();
|
||||
if (k.begins_with("[")) {
|
||||
section = k.substr(1, k.length() - 2).strip_edges().to_upper();
|
||||
print_line("Section: " + section);
|
||||
} else if (k != String()) {
|
||||
if (!manifest_sections.has(section)) {
|
||||
manifest_sections[section] = List<String>();
|
||||
}
|
||||
manifest_sections[section].push_back(l);
|
||||
}
|
||||
}
|
||||
|
||||
f->close();
|
||||
}
|
||||
}
|
||||
//parse gradle
|
||||
{
|
||||
FileAccessRef f = FileAccess::open(String("res://android").plus_file(d).plus_file("gradle.conf"), FileAccess::READ);
|
||||
if (f) {
|
||||
|
||||
String section;
|
||||
while (!f->eof_reached()) {
|
||||
String l = f->get_line().strip_edges();
|
||||
String k = l.strip_edges();
|
||||
if (k.begins_with("[")) {
|
||||
section = k.substr(1, k.length() - 2).strip_edges().to_upper();
|
||||
print_line("Section: " + section);
|
||||
} else if (k != String()) {
|
||||
if (!gradle_sections.has(section)) {
|
||||
gradle_sections[section] = List<String>();
|
||||
}
|
||||
gradle_sections[section].push_back(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
d = da->get_next();
|
||||
}
|
||||
da->list_dir_end();
|
||||
|
||||
{ //fix gradle build
|
||||
|
||||
String new_file;
|
||||
{
|
||||
FileAccessRef f = FileAccess::open("res://android/build/build.gradle", FileAccess::READ);
|
||||
if (f) {
|
||||
|
||||
while (!f->eof_reached()) {
|
||||
String l = f->get_line();
|
||||
|
||||
if (l.begins_with("//CHUNK_")) {
|
||||
String text = l.replace_first("//CHUNK_", "");
|
||||
int begin_pos = text.find("_BEGIN");
|
||||
if (begin_pos != -1) {
|
||||
text = text.substr(0, begin_pos);
|
||||
text = text.to_upper(); //just in case
|
||||
|
||||
String end_marker = "//CHUNK_" + text + "_END";
|
||||
size_t pos = f->get_position();
|
||||
bool found = false;
|
||||
while (!f->eof_reached()) {
|
||||
l = f->get_line();
|
||||
if (l.begins_with(end_marker)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_file += "//CHUNK_" + text + "_BEGIN\n";
|
||||
|
||||
if (!found) {
|
||||
ERR_PRINT("No end marker found in build.gradle for chunk: " + text);
|
||||
f->seek(pos);
|
||||
} else {
|
||||
|
||||
//add chunk lines
|
||||
if (gradle_sections.has(text)) {
|
||||
for (List<String>::Element *E = gradle_sections[text].front(); E; E = E->next()) {
|
||||
new_file += E->get() + "\n";
|
||||
}
|
||||
}
|
||||
new_file += end_marker + "\n";
|
||||
}
|
||||
} else {
|
||||
new_file += l + "\n"; //pass line by
|
||||
}
|
||||
} else if (l.begins_with("//DIR_")) {
|
||||
String text = l.replace_first("//DIR_", "");
|
||||
int begin_pos = text.find("_BEGIN");
|
||||
if (begin_pos != -1) {
|
||||
text = text.substr(0, begin_pos);
|
||||
text = text.to_upper(); //just in case
|
||||
|
||||
String end_marker = "//DIR_" + text + "_END";
|
||||
size_t pos = f->get_position();
|
||||
bool found = false;
|
||||
while (!f->eof_reached()) {
|
||||
l = f->get_line();
|
||||
if (l.begins_with(end_marker)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_file += "//DIR_" + text + "_BEGIN\n";
|
||||
|
||||
if (!found) {
|
||||
ERR_PRINT("No end marker found in build.gradle for dir: " + text);
|
||||
f->seek(pos);
|
||||
} else {
|
||||
//add chunk lines
|
||||
if (directory_paths.has(text)) {
|
||||
for (List<String>::Element *E = directory_paths[text].front(); E; E = E->next()) {
|
||||
new_file += ",'" + E->get().replace("'", "\'") + "'";
|
||||
new_file += "\n";
|
||||
}
|
||||
}
|
||||
new_file += end_marker + "\n";
|
||||
}
|
||||
} else {
|
||||
new_file += l + "\n"; //pass line by
|
||||
}
|
||||
|
||||
} else {
|
||||
new_file += l + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileAccessRef f = FileAccess::open("res://android/build/build.gradle", FileAccess::WRITE);
|
||||
f->store_string(new_file);
|
||||
f->close();
|
||||
}
|
||||
|
||||
{ //fix manifest
|
||||
|
||||
String new_file;
|
||||
{
|
||||
FileAccessRef f = FileAccess::open("res://android/build/AndroidManifest.xml", FileAccess::READ);
|
||||
if (f) {
|
||||
|
||||
while (!f->eof_reached()) {
|
||||
String l = f->get_line();
|
||||
|
||||
if (l.begins_with("<!--CHUNK_")) {
|
||||
String text = l.replace_first("<!--CHUNK_", "");
|
||||
int begin_pos = text.find("_BEGIN-->");
|
||||
if (begin_pos != -1) {
|
||||
text = text.substr(0, begin_pos);
|
||||
text = text.to_upper(); //just in case
|
||||
|
||||
String end_marker = "<!--CHUNK_" + text + "_END-->";
|
||||
size_t pos = f->get_position();
|
||||
bool found = false;
|
||||
while (!f->eof_reached()) {
|
||||
l = f->get_line();
|
||||
if (l.begins_with(end_marker)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_file += "<!--CHUNK_" + text + "_BEGIN-->\n";
|
||||
|
||||
if (!found) {
|
||||
ERR_PRINT("No end marker found in AndroidManifest.xml for chunk: " + text);
|
||||
f->seek(pos);
|
||||
} else {
|
||||
//add chunk lines
|
||||
if (manifest_sections.has(text)) {
|
||||
for (List<String>::Element *E = manifest_sections[text].front(); E; E = E->next()) {
|
||||
new_file += E->get() + "\n";
|
||||
}
|
||||
}
|
||||
new_file += end_marker + "\n";
|
||||
}
|
||||
} else {
|
||||
new_file += l + "\n"; //pass line by
|
||||
}
|
||||
|
||||
} else if (l.strip_edges().begins_with("<application")) {
|
||||
String last_tag = "android:icon=\"@mipmap/icon\"";
|
||||
int last_tag_pos = l.find(last_tag);
|
||||
if (last_tag_pos == -1) {
|
||||
ERR_PRINT("Not adding application attributes as the expected tag was not found in '<application': " + last_tag);
|
||||
new_file += l + "\n";
|
||||
} else {
|
||||
String base = l.substr(0, last_tag_pos + last_tag.length());
|
||||
if (manifest_sections.has("application_attribs")) {
|
||||
for (List<String>::Element *E = manifest_sections["application_attribs"].front(); E; E = E->next()) {
|
||||
String to_add = E->get().strip_edges();
|
||||
base += " " + to_add + " ";
|
||||
}
|
||||
}
|
||||
base += ">\n";
|
||||
new_file += base;
|
||||
}
|
||||
} else {
|
||||
new_file += l + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileAccessRef f = FileAccess::open("res://android/build/AndroidManifest.xml", FileAccess::WRITE);
|
||||
f->store_string(new_file);
|
||||
f->close();
|
||||
}
|
||||
}
|
||||
|
||||
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) {
|
||||
|
||||
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
|
||||
@@ -2025,8 +1779,6 @@ public:
|
||||
|
||||
ERR_FAIL_COND_V_MSG(sdk_path == "", ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/custom_build_sdk_path'.");
|
||||
|
||||
_update_custom_build_project();
|
||||
|
||||
OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required
|
||||
|
||||
String build_command;
|
||||
@@ -2037,14 +1789,18 @@ public:
|
||||
#endif
|
||||
|
||||
String build_path = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/build");
|
||||
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/plugins");
|
||||
|
||||
build_command = build_path.plus_file(build_command);
|
||||
|
||||
String package_name = get_package_name(p_preset->get("package/unique_name"));
|
||||
String plugins = p_preset->get("custom_template/plugins");
|
||||
|
||||
List<String> cmdline;
|
||||
cmdline.push_back("build");
|
||||
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
|
||||
cmdline.push_back("-Pcustom_template_plugins_dir=" + plugins_dir); // argument to specify the plugins directory.
|
||||
cmdline.push_back("-Pcustom_template_plugins=" + plugins); // argument to specify the list of plugins to enable.
|
||||
cmdline.push_back("-p"); // argument to specify the start directory.
|
||||
cmdline.push_back(build_path); // start directory.
|
||||
/*{ used for debug
|
||||
|
||||
Reference in New Issue
Block a user