use crate::export::{asset, utils, ExportOptions};
use cargo_metadata::{camino::Utf8Path, Metadata, Package};
use fyrox_core::{log::Log, platform::TargetPlatform};
use fyrox_resource::manager::ResourceManager;
use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
process::Stdio,
};
pub fn build_package(
package_name: &str,
build_target: &str,
enable_optimization: bool,
) -> std::process::Command {
let mut process = utils::make_command("cargo-apk");
process
.stderr(Stdio::piped())
.arg("apk")
.arg("build")
.arg("--package")
.arg(package_name)
.arg("--target")
.arg(build_target);
if enable_optimization {
process.arg("--release");
}
process
}
pub fn copy_binaries(
metadata: &Metadata,
package_name: &str,
destination_folder: &Path,
) -> Result<(), String> {
Log::info("Trying to copy the apk...");
let mut binary_paths = vec![];
for entry in fs::read_dir(metadata.target_directory.join("release/apk"))
.unwrap()
.flatten()
{
if let Ok(file_metadata) = entry.metadata() {
if !file_metadata.file_type().is_file() {
continue;
}
}
if let Some(stem) = entry.path().file_stem() {
if stem == OsStr::new(package_name) {
binary_paths.push(entry.path());
}
}
}
for path in binary_paths {
if let Some(file_name) = path.file_name() {
match fs::copy(&path, destination_folder.join(file_name)) {
Ok(_) => {
Log::info(format!(
"{} was successfully copied to the {} folder.",
path.display(),
destination_folder.display()
));
}
Err(err) => {
Log::warn(format!(
"Failed to copy {} file to the {} folder. Reason: {:?}",
path.display(),
destination_folder.display(),
err
));
}
}
}
}
Ok(())
}
pub fn run_build(package_name: &str, destination_folder: &Path) {
if let Ok(adb) = utils::make_command("adb")
.current_dir(destination_folder)
.arg("install")
.arg(format!("{package_name}.apk"))
.spawn()
{
match adb.wait_with_output() {
Ok(_) => {
let compatible_package_name = package_name.replace('-', "_");
Log::verify(
utils::make_command("adb")
.arg("shell")
.arg("am")
.arg("start")
.arg("-n")
.arg(format!(
"rust.{compatible_package_name}/android.app.NativeActivity"
))
.spawn(),
);
}
Err(err) => Log::err(format!("ADB error: {err:?}")),
}
}
}
pub fn copy_assets(
export_options: &ExportOptions,
package: &Package,
package_dir_path: &Utf8Path,
temp_folders: &mut Vec<PathBuf>,
resource_manager: &ResourceManager,
convert: bool,
) -> Result<(), String> {
if let Some(assets) = package
.metadata
.get("android")
.and_then(|v| v.get("assets"))
.and_then(|v| v.as_str())
{
let temp_assets_storage = package_dir_path.join(assets).as_std_path().to_path_buf();
Log::info(format!(
"Trying to copy the assets to a temporary storage {}...",
temp_assets_storage.display()
));
if !temp_assets_storage.exists() {
Log::verify(std::fs::create_dir_all(&temp_assets_storage));
}
temp_folders.push(temp_assets_storage.clone());
for folder in &export_options.assets_folders {
Log::info(format!(
"Trying to copy assets from {} to {}...",
folder.display(),
temp_assets_storage.display()
));
Log::verify(asset::copy_and_convert_assets(
folder,
temp_assets_storage.join(folder),
TargetPlatform::Android,
&|_| true,
resource_manager,
convert,
));
}
Ok(())
} else {
Err("Android executor must specify assets folder in \
[package.metadata.android] section"
.to_string())
}
}