summaryrefslogtreecommitdiff
path: root/platform/android/export
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/export')
-rw-r--r--platform/android/export/export.cpp302
1 files changed, 188 insertions, 114 deletions
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 6b4d0ff8c4..b76b0d5dbe 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -228,7 +228,7 @@ class EditorExportAndroid : public EditorExportPlatform {
};
Vector<Device> devices;
- bool devices_changed;
+ volatile bool devices_changed;
Mutex *device_lock;
Thread *device_thread;
volatile bool quit_request;
@@ -257,7 +257,6 @@ class EditorExportAndroid : public EditorExportPlatform {
if (dpos == -1)
continue;
d = d.substr(0, dpos).strip_edges();
- //print_line("found device: "+d);
ldevices.push_back(d);
}
@@ -301,8 +300,7 @@ class EditorExportAndroid : public EditorExportPlatform {
args.push_back("-s");
args.push_back(d.id);
args.push_back("shell");
- args.push_back("cat");
- args.push_back("/system/build.prop");
+ args.push_back("getprop");
int ec;
String dp;
@@ -315,7 +313,14 @@ class EditorExportAndroid : public EditorExportPlatform {
d.api_level = 0;
for (int j = 0; j < props.size(); j++) {
+ // got information by `shell cat /system/build.prop` before and its format is "property=value"
+ // it's now changed to use `shell getporp` because of permission issue with Android 8.0 and above
+ // its format is "[property]: [value]" so changed it as like build.prop
String p = props[j];
+ p = p.replace("]: ", "=");
+ p = p.replace("[", "");
+ p = p.replace("]", "");
+
if (p.begins_with("ro.product.model=")) {
device = p.get_slice("=", 1).strip_edges();
} else if (p.begins_with("ro.product.brand=")) {
@@ -339,8 +344,6 @@ class EditorExportAndroid : public EditorExportPlatform {
}
d.name = vendor + " " + device;
- //print_line("name: "+d.name);
- //print_line("description: "+d.description);
}
ndevices.push_back(d);
@@ -522,11 +525,9 @@ class EditorExportAndroid : public EditorExportPlatform {
bool exported = false;
for (int i = 0; i < p_so.tags.size(); ++i) {
// shared objects can be fat (compatible with multiple ABIs)
- int start_pos = 0;
int abi_index = abis.find(p_so.tags[i]);
if (abi_index != -1) {
exported = true;
- start_pos = abi_index + 1;
String abi = abis[abi_index];
String dst_path = "lib/" + abi + "/" + p_so.path.get_file();
Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
@@ -564,7 +565,7 @@ class EditorExportAndroid : public EditorExportPlatform {
// const int CHUNK_RESOURCEIDS = 0x00080180;
const int CHUNK_STRINGS = 0x001C0001;
// const int CHUNK_XML_END_NAMESPACE = 0x00100101;
- // const int CHUNK_XML_END_TAG = 0x00100103;
+ const int CHUNK_XML_END_TAG = 0x00100103;
// const int CHUNK_XML_START_NAMESPACE = 0x00100100;
const int CHUNK_XML_START_TAG = 0x00100102;
// const int CHUNK_XML_TEXT = 0x00100104;
@@ -595,24 +596,28 @@ class EditorExportAndroid : public EditorExportPlatform {
bool screen_support_large = p_preset->get("screen/support_large");
bool screen_support_xlarge = p_preset->get("screen/support_xlarge");
- String user_perms[MAX_USER_PERMISSIONS];
-
- for (int i = 0; i < MAX_USER_PERMISSIONS; i++) {
-
- user_perms[i] = p_preset->get("user_permissions/" + itos(i));
- }
-
- Set<String> perms;
+ Vector<String> perms;
const char **aperms = android_perms;
while (*aperms) {
bool enabled = p_preset->get("permissions/" + String(*aperms).to_lower());
if (enabled)
- perms.insert(String(*aperms));
+ perms.push_back("android.permission." + String(*aperms));
aperms++;
}
+ for (int i = 0; i < MAX_USER_PERMISSIONS; i++) {
+ String user_perm = p_preset->get("user_permissions/" + itos(i));
+ if (user_perm.strip_edges() != "" && user_perm.strip_edges() != "False")
+ perms.push_back(user_perm.strip_edges());
+ }
+
+ if (p_give_internet) {
+ if (perms.find("android.permission.INTERNET") == -1)
+ perms.push_back("android.permission.INTERNET");
+ }
+
while (ofs < (uint32_t)p_manifest.size()) {
uint32_t chunk = decode_uint32(&p_manifest[ofs]);
@@ -657,25 +662,20 @@ class EditorExportAndroid : public EditorExportPlatform {
ucstring.resize(len + 1);
for (uint32_t j = 0; j < len; j++) {
uint16_t c = decode_uint16(&p_manifest[string_at + 2 + 2 * j]);
- ucstring[j] = c;
+ ucstring.write[j] = c;
}
string_end = MAX(string_at + 2 + 2 * len, string_end);
- ucstring[len] = 0;
- string_table[i] = ucstring.ptr();
+ ucstring.write[len] = 0;
+ string_table.write[i] = ucstring.ptr();
}
-
- //print_line("String "+itos(i)+": "+string_table[i]);
}
for (uint32_t i = string_end; i < (ofs + size); i++) {
stable_extra.push_back(p_manifest[i]);
}
- //printf("stable extra: %i\n",int(stable_extra.size()));
string_table_ends = ofs + size;
- //print_line("STABLE SIZE: "+itos(size)+" ACTUAL: "+itos(string_table_ends));
-
} break;
case CHUNK_XML_START_TAG: {
@@ -706,79 +706,132 @@ class EditorExportAndroid : public EditorExportPlatform {
//replace project information
if (tname == "manifest" && attrname == "package") {
-
- print_line("FOUND package");
- string_table[attr_value] = get_package_name(package_name);
+ string_table.write[attr_value] = get_package_name(package_name);
}
- if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionCode") {
-
- print_line("FOUND versionCode");
- encode_uint32(version_code, &p_manifest[iofs + 16]);
+ if (tname == "manifest" && attrname == "versionCode") {
+ encode_uint32(version_code, &p_manifest.write[iofs + 16]);
}
- if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionName") {
-
- print_line("FOUND versionName");
+ if (tname == "manifest" && attrname == "versionName") {
if (attr_value == 0xFFFFFFFF) {
WARN_PRINT("Version name in a resource, should be plaintext")
} else
- string_table[attr_value] = version_name;
+ string_table.write[attr_value] = version_name;
}
- if (tname == "activity" && /*nspace=="android" &&*/ attrname == "screenOrientation") {
+ if (tname == "activity" && attrname == "screenOrientation") {
- encode_uint32(orientation == 0 ? 0 : 1, &p_manifest[iofs + 16]);
+ encode_uint32(orientation == 0 ? 0 : 1, &p_manifest.write[iofs + 16]);
}
- if (tname == "uses-feature" && /*nspace=="android" &&*/ attrname == "glEsVersion") {
- print_line("version number: " + itos(decode_uint32(&p_manifest[iofs + 16])));
- }
+ if (tname == "supports-screens") {
- if (tname == "uses-permission" && /*nspace=="android" &&*/ attrname == "name") {
+ if (attrname == "smallScreens") {
- if (value.begins_with("godot.custom")) {
+ encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
- int which = value.get_slice(".", 2).to_int();
- if (which >= 0 && which < MAX_USER_PERMISSIONS && user_perms[which].strip_edges() != "") {
+ } else if (attrname == "normalScreens") {
- string_table[attr_value] = user_perms[which].strip_edges();
- }
+ encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
- } else if (value.begins_with("godot.")) {
- String perm = value.get_slice(".", 1);
+ } else if (attrname == "largeScreens") {
- if (perms.has(perm) || (p_give_internet && perm == "INTERNET")) {
+ encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
- print_line("PERM: " + perm);
- string_table[attr_value] = "android.permission." + perm;
- }
+ } else if (attrname == "xlargeScreens") {
+
+ encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
}
- if (tname == "supports-screens") {
+ iofs += 20;
+ }
- if (attrname == "smallScreens") {
+ } break;
+ case CHUNK_XML_END_TAG: {
+ int iofs = ofs + 8;
+ uint32_t name = decode_uint32(&p_manifest[iofs + 12]);
+ String tname = string_table[name];
- encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ if (tname == "manifest") {
- } else if (attrname == "normalScreens") {
+ // save manifest ending so we can restore it
+ Vector<uint8_t> manifest_end;
+ uint32_t manifest_cur_size = p_manifest.size();
+ uint32_t node_size = size;
- encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ manifest_end.resize(p_manifest.size() - ofs);
+ memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
- } else if (attrname == "largeScreens") {
+ int32_t attr_name_string = string_table.find("name");
+ ERR_EXPLAIN("Template does not have 'name' attribute");
+ ERR_FAIL_COND(attr_name_string == -1);
- encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ int32_t ns_android_string = string_table.find("android");
+ ERR_EXPLAIN("Template does not have 'android' namespace");
+ ERR_FAIL_COND(ns_android_string == -1);
- } else if (attrname == "xlargeScreens") {
+ int32_t attr_uses_permission_string = string_table.find("uses-permission");
+ if (attr_uses_permission_string == -1) {
+ string_table.push_back("uses-permission");
+ attr_uses_permission_string = string_table.size() - 1;
+ }
+
+ for (int i = 0; i < perms.size(); ++i) {
+ print_line("Adding permission " + perms[i]);
- encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ manifest_cur_size += 56 + 24; // node + end node
+ p_manifest.resize(manifest_cur_size);
+
+ // Add permission to the string pool
+ int32_t perm_string = string_table.find(perms[i]);
+ if (perm_string == -1) {
+ string_table.push_back(perms[i]);
+ perm_string = string_table.size() - 1;
}
+
+ // start tag
+ encode_uint16(0x102, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(56, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+ encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start
+ encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size
+ encode_uint16(1, &p_manifest.write[ofs + 28]); // num_attrs
+ encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index
+ encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index
+ encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index
+
+ // attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns
+ encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name'
+ encode_uint32(perm_string, &p_manifest.write[ofs + 44]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size
+ p_manifest.write[ofs + 50] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string)
+ encode_uint32(perm_string, &p_manifest.write[ofs + 52]); // typedvalue reference
+
+ ofs += 56;
+
+ // end tag
+ encode_uint16(0x103, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(24, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+
+ ofs += 24;
}
- iofs += 20;
+ // copy footer back in
+ memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size());
}
-
} break;
}
@@ -792,25 +845,25 @@ class EditorExportAndroid : public EditorExportPlatform {
for (uint32_t i = 0; i < string_table_begins; i++) {
- ret[i] = p_manifest[i];
+ ret.write[i] = p_manifest[i];
}
ofs = 0;
for (int i = 0; i < string_table.size(); i++) {
- encode_uint32(ofs, &ret[string_table_begins + i * 4]);
+ encode_uint32(ofs, &ret.write[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
- //print_line("ofs: "+itos(i)+": "+itos(ofs));
}
+
ret.resize(ret.size() + ofs);
- uint8_t *chars = &ret[ret.size() - ofs];
+ string_data_offset = ret.size() - ofs;
+ uint8_t *chars = &ret.write[string_data_offset];
for (int i = 0; i < string_table.size(); i++) {
String s = string_table[i];
- //print_line("savint string :"+s);
encode_uint16(s.length(), chars);
chars += 2;
- for (int j = 0; j < s.length(); j++) { //include zero?
+ for (int j = 0; j < s.length(); j++) {
encode_uint16(s[j], chars);
chars += 2;
}
@@ -822,6 +875,7 @@ class EditorExportAndroid : public EditorExportPlatform {
ret.push_back(stable_extra[i]);
}
+ //pad
while (ret.size() % 4)
ret.push_back(0);
@@ -830,15 +884,15 @@ class EditorExportAndroid : public EditorExportPlatform {
uint32_t extra = (p_manifest.size() - string_table_ends);
ret.resize(new_stable_end + extra);
for (uint32_t i = 0; i < extra; i++)
- ret[new_stable_end + i] = p_manifest[string_table_ends + i];
+ ret.write[new_stable_end + i] = p_manifest[string_table_ends + i];
while (ret.size() % 4)
ret.push_back(0);
- encode_uint32(ret.size(), &ret[4]); //update new file size
-
- encode_uint32(new_stable_end - 8, &ret[12]); //update new string table size
+ encode_uint32(ret.size(), &ret.write[4]); //update new file size
- //print_line("file size: "+itos(ret.size()));
+ encode_uint32(new_stable_end - 8, &ret.write[12]); //update new string table size
+ encode_uint32(string_table.size(), &ret.write[16]); //update new number of strings
+ encode_uint32(string_data_offset - 8, &ret.write[28]); //update new string data offset
p_manifest = ret;
}
@@ -860,9 +914,9 @@ class EditorExportAndroid : public EditorExportPlatform {
Vector<uint8_t> str8;
str8.resize(len + 1);
for (uint32_t i = 0; i < len; i++) {
- str8[i] = p_bytes[offset + i];
+ str8.write[i] = p_bytes[offset + i];
}
- str8[len] = 0;
+ str8.write[len] = 0;
String str;
str.parse_utf8((const char *)str8.ptr());
return str;
@@ -881,7 +935,6 @@ class EditorExportAndroid : public EditorExportPlatform {
void _fix_resources(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest) {
const int UTF8_FLAG = 0x00000100;
- print_line("*******************GORRRGLE***********************");
uint32_t string_block_len = decode_uint32(&p_manifest[16]);
uint32_t string_count = decode_uint32(&p_manifest[20]);
@@ -926,18 +979,18 @@ class EditorExportAndroid : public EditorExportPlatform {
for (uint32_t i = 0; i < string_table_begins; i++) {
- ret[i] = p_manifest[i];
+ ret.write[i] = p_manifest[i];
}
int ofs = 0;
for (int i = 0; i < string_table.size(); i++) {
- encode_uint32(ofs, &ret[string_table_begins + i * 4]);
+ encode_uint32(ofs, &ret.write[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
}
ret.resize(ret.size() + ofs);
- uint8_t *chars = &ret[ret.size() - ofs];
+ uint8_t *chars = &ret.write[ret.size() - ofs];
for (int i = 0; i < string_table.size(); i++) {
String s = string_table[i];
@@ -956,19 +1009,19 @@ class EditorExportAndroid : public EditorExportPlatform {
ret.push_back(0);
//change flags to not use utf8
- encode_uint32(string_flags & ~0x100, &ret[28]);
+ encode_uint32(string_flags & ~0x100, &ret.write[28]);
//change length
- encode_uint32(ret.size() - 12, &ret[16]);
+ encode_uint32(ret.size() - 12, &ret.write[16]);
//append the rest...
int rest_from = 12 + string_block_len;
int rest_to = ret.size();
int rest_len = (p_manifest.size() - rest_from);
ret.resize(ret.size() + (p_manifest.size() - rest_from));
for (int i = 0; i < rest_len; i++) {
- ret[rest_to + i] = p_manifest[rest_from + i];
+ ret.write[rest_to + i] = p_manifest[rest_from + i];
}
//finally update the size
- encode_uint32(ret.size(), &ret[4]);
+ encode_uint32(ret.size(), &ret.write[4]);
p_manifest = ret;
//printf("end\n");
@@ -1011,16 +1064,15 @@ public:
virtual void get_export_options(List<ExportOption> *r_options) {
- /*r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1));*/
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
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,65535,1"), 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, "package/unique_name"), "org.godotengine.$genname"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.$genname"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "screen/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait"), 0));
@@ -1030,10 +1082,10 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
}
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "keystore"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false));
@@ -1058,8 +1110,6 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "user_permissions/" + itos(i)), false));
}
-
- //r_options->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
}
virtual String get_name() const {
@@ -1077,7 +1127,10 @@ public:
virtual bool poll_devices() {
bool dc = devices_changed;
- devices_changed = false;
+ if (dc) {
+ // don't clear unless we're reporting true, to avoid race
+ devices_changed = false;
+ }
return dc;
}
@@ -1147,7 +1200,7 @@ public:
String package_name = p_preset->get("package/unique_name");
if (remove_prev) {
- ep.step("Uninstalling..", 1);
+ ep.step("Uninstalling...", 1);
print_line("Uninstalling previous version: " + devices[p_device].name);
@@ -1159,8 +1212,8 @@ public:
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
}
- print_line("Installing into device (please wait..): " + devices[p_device].name);
- ep.step("Installing to Device (please wait..)..", 2);
+ print_line("Installing to device (please wait...): " + devices[p_device].name);
+ ep.step("Installing to device (please wait...)", 2);
args.clear();
args.push_back("-s");
@@ -1226,7 +1279,7 @@ public:
}
}
- ep.step("Running on Device..", 3);
+ ep.step("Running on Device...", 3);
args.clear();
args.push_back("-s");
args.push_back(devices[p_device].id);
@@ -1258,12 +1311,28 @@ public:
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+ String err;
r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String();
+ if (p_preset->get("custom_package/debug") != "") {
+ if (FileAccess::exists(p_preset->get("custom_package/debug"))) {
+ r_missing_templates = false;
+ } else {
+ err += "Custom debug package not found.\n";
+ }
+ }
+
+ if (p_preset->get("custom_package/release") != "") {
+ if (FileAccess::exists(p_preset->get("custom_package/release"))) {
+ r_missing_templates = false;
+ } else {
+ err += "Custom release package not found.\n";
+ }
+ }
+
bool valid = !r_missing_templates;
String adb = EditorSettings::get_singleton()->get("export/android/adb");
- String err;
if (!FileAccess::exists(adb)) {
@@ -1317,6 +1386,8 @@ public:
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);
+
String src_apk;
EditorProgress ep("export", "Exporting for Android", 105);
@@ -1484,7 +1555,7 @@ public:
ret = unzGoToNextFile(pkg);
}
- ep.step("Adding Files..", 1);
+ ep.step("Adding Files...", 1);
Error err = OK;
Vector<String> cl = cmdline.strip_edges().split(" ");
for (int i = 0; i < cl.size(); i++) {
@@ -1564,7 +1635,7 @@ public:
//add comandline
Vector<uint8_t> clf;
clf.resize(4);
- encode_uint32(cl.size(), &clf[0]);
+ encode_uint32(cl.size(), &clf.write[0]);
for (int i = 0; i < cl.size(); i++) {
print_line(itos(i) + " param: " + cl[i]);
@@ -1574,8 +1645,8 @@ public:
if (!length)
continue;
clf.resize(base + 4 + length);
- encode_uint32(length, &clf[base]);
- copymem(&clf[base + 4], txt.ptr(), length);
+ encode_uint32(length, &clf.write[base]);
+ copymem(&clf.write[base + 4], txt.ptr(), length);
}
zip_fileinfo zipfi = get_zip_fileinfo();
@@ -1618,14 +1689,14 @@ public:
password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
- ep.step("Signing Debug APK..", 103);
+ ep.step("Signing Debug APK...", 103);
} else {
keystore = release_keystore;
password = release_password;
user = release_username;
- ep.step("Signing Release APK..", 103);
+ ep.step("Signing Release APK...", 103);
}
if (!FileAccess::exists(keystore)) {
@@ -1635,9 +1706,9 @@ public:
List<String> args;
args.push_back("-digestalg");
- args.push_back("SHA1");
+ args.push_back("SHA-256");
args.push_back("-sigalg");
- args.push_back("MD5withRSA");
+ args.push_back("SHA256withRSA");
String tsa_url = EditorSettings::get_singleton()->get("export/android/timestamping_authority_url");
if (tsa_url != "") {
args.push_back("-tsa");
@@ -1657,7 +1728,7 @@ public:
return ERR_CANT_CREATE;
}
- ep.step("Verifying APK..", 104);
+ ep.step("Verifying APK...", 104);
args.clear();
args.push_back("-verify");
@@ -1677,7 +1748,7 @@ public:
static const int ZIP_ALIGNMENT = 4;
- ep.step("Aligning APK..", 105);
+ ep.step("Aligning APK...", 105);
unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io);
if (!tmp_unaligned) {
@@ -1767,6 +1838,9 @@ public:
r_features->push_back("Android");
}
+ virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) {
+ }
+
EditorExportAndroid() {
Ref<Image> img = memnew(Image(_android_logo));
@@ -1778,9 +1852,9 @@ public:
run_icon->create_from_image(img);
device_lock = Mutex::create();
- device_thread = Thread::create(_device_poll_thread, this);
devices_changed = true;
quit_request = false;
+ device_thread = Thread::create(_device_poll_thread, this);
}
~EditorExportAndroid() {
@@ -1803,7 +1877,7 @@ void register_android_exporter() {
EDITOR_DEF("export/android/jarsigner", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/jarsigner", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
EDITOR_DEF("export/android/debug_keystore", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "keystore"));
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/force_system_user", false);