Browse Source

Add missing zip alignment step for generated apks.

Fredia Huya-Kouadio 4 years ago
parent
commit
380022637e
1 changed files with 80 additions and 2 deletions
  1. 80 2
      platform/android/export/export.cpp

+ 80 - 2
platform/android/export/export.cpp

@@ -2027,9 +2027,21 @@ public:
 				valid = false;
 			} else {
 				Error errn;
+				// Check for the platform-tools directory.
 				DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn);
 				if (errn != OK) {
-					err += TTR("Invalid Android SDK path for custom build in Editor Settings.") + "\n";
+					err += TTR("Invalid Android SDK path for custom build in Editor Settings.");
+					err += TTR("Missing 'platform-tools' directory!");
+					err += "\n";
+					valid = false;
+				}
+
+				// Check for the build-tools directory.
+				DirAccessRef build_tools_da = DirAccess::open(sdk_path.plus_file("build-tools"), &errn);
+				if (errn != OK) {
+					err += TTR("Invalid Android SDK path for custom build in Editor Settings.");
+					err += TTR("Missing 'build-tools' directory!");
+					err += "\n";
 					valid = false;
 				}
 			}
@@ -2617,6 +2629,58 @@ public:
 		}
 	}
 
+	Error _zip_align_project(const String &sdk_path, const String &unaligned_file_path, const String &aligned_file_path) {
+		// Look for the zipalign tool.
+		String zipalign_command;
+		Error errn;
+		String build_tools_dir = sdk_path.plus_file("build-tools");
+		DirAccessRef da = DirAccess::open(build_tools_dir, &errn);
+		if (errn != OK) {
+			return errn;
+		}
+
+		// There are additional versions directories we need to go through.
+		da->list_dir_begin();
+		String sub_dir = da->get_next();
+		while (!sub_dir.empty()) {
+			if (!sub_dir.begins_with(".") && da->current_is_dir()) {
+				// Check if the tool is here.
+				String tool_path = build_tools_dir.plus_file(sub_dir).plus_file("zipalign");
+				if (FileAccess::exists(tool_path)) {
+					zipalign_command = tool_path;
+					break;
+				}
+			}
+			sub_dir = da->get_next();
+		}
+		da->list_dir_end();
+
+		if (zipalign_command.empty()) {
+			EditorNode::get_singleton()->show_warning(TTR("Unable to find the zipalign tool."));
+			return ERR_CANT_CREATE;
+		}
+
+		List<String> zipalign_args;
+		zipalign_args.push_back("-f");
+		zipalign_args.push_back("-v");
+		zipalign_args.push_back("4");
+		zipalign_args.push_back(unaligned_file_path); // source file
+		zipalign_args.push_back(aligned_file_path); // destination file
+
+		int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Aligning APK..."), zipalign_command, zipalign_args);
+		if (result != 0) {
+			EditorNode::get_singleton()->show_warning(TTR("Unable to complete APK alignment."));
+			return ERR_CANT_CREATE;
+		}
+
+		// Delete the unaligned path.
+		errn = da->remove(unaligned_file_path);
+		if (errn != OK) {
+			EditorNode::get_singleton()->show_warning(TTR("Unable to delete unaligned APK."));
+		}
+		return OK;
+	}
+
 	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);
@@ -2786,11 +2850,16 @@ public:
 			copy_args.push_back(build_path); // start directory.
 
 			String export_filename = p_path.get_file();
+			if (export_format == 0) {
+				// By default, generated apk are not aligned.
+				export_filename += ".unaligned";
+			}
 			String export_path = p_path.get_base_dir();
 			if (export_path.is_rel_path()) {
 				export_path = OS::get_singleton()->get_resource_dir().plus_file(export_path);
 			}
 			export_path = ProjectSettings::get_singleton()->globalize_path(export_path).simplify_path();
+			String export_file_path = export_path.plus_file(export_filename);
 
 			copy_args.push_back("-Pexport_path=file:" + export_path);
 			copy_args.push_back("-Pexport_filename=" + export_filename);
@@ -2802,11 +2871,20 @@ public:
 			}
 
 			if (_signed) {
-				err = sign_apk(p_preset, p_debug, p_path, ep);
+				err = sign_apk(p_preset, p_debug, export_file_path, ep);
 				if (err != OK) {
 					return err;
 				}
 			}
+
+			if (export_format == 0) {
+				// Perform zip alignment
+				err = _zip_align_project(sdk_path, export_file_path, export_path.plus_file(p_path.get_file()));
+				if (err != OK) {
+					return err;
+				}
+			}
+
 			return OK;
 		}
 		// This is the start of the Legacy build system