android_tools/aapt2/
mod.rs

1//! Android Asset Packaging Tool 2.0 (AAPT2).
2//! https://developer.android.com/studio/command-line/aapt2
3//! https://android.googlesource.com/platform/frameworks/base/+/master/tools/aapt2
4//!
5//! The main idea behind `AAPT2`, apart from new features, is that it divides
6//! the 'package' step into two: 'compile' and 'link'. It improves performance,
7//! since if only one file changes, you only need to recompile that one file and
8//! link all the intermediate files with the 'link' command.
9
10mod compile;
11mod convert;
12mod daemon;
13mod diff;
14mod dump;
15mod link;
16mod optimize;
17mod version;
18
19pub use compile::*;
20pub use convert::*;
21pub use daemon::*;
22pub use diff::*;
23pub use dump::*;
24pub use link::*;
25pub use optimize::*;
26pub use version::*;
27
28use self::{daemon::Aapt2Daemon, diff::Aapt2Diff, version::Aapt2Version};
29use crate::{error::*, find_max_version, sdk_path_from_env};
30use std::{
31    path::{Path, PathBuf},
32    process::Command,
33};
34
35/// [`AAPT2`](https://developer.android.com/studio/command-line/aapt2)
36/// (Android Asset Packaging Tool) is a build tool that Android Studio
37/// and Android Gradle Plugin use to compile and package your app’s resources.
38/// [`AAPT2`] parses, indexes, and compiles the resources into a binary format
39/// that is optimized for the Android platform
40#[derive(Clone, Copy)]
41pub struct Aapt2;
42
43impl Aapt2 {
44    /// Compiles resources incrementally from given resource path
45    pub fn compile_incremental(self, res_path: &Path, compiled_res: &Path) -> Aapt2Compile {
46        Aapt2Compile::new(res_path, compiled_res)
47    }
48
49    /// Compiles resources from given resource dir
50    pub fn compile_dir(self, res_dir: &Path, compiled_res: &Path) -> Aapt2Compile {
51        Aapt2Compile::new_from_res_dir(res_dir, compiled_res)
52    }
53
54    /// Compiles resources from given resource zip
55    pub fn compile_zip(self, res_zip: &Path, compiled_res: &Path) -> Aapt2Compile {
56        Aapt2Compile::new_from_res_zip(res_zip, compiled_res)
57    }
58
59    /// Links given list of resources into an APK
60    pub fn link_inputs(self, inputs: &[PathBuf], output_apk: &Path, manifest: &Path) -> Aapt2Link {
61        Aapt2Link::new(inputs, output_apk, manifest)
62    }
63
64    /// Links resources from given /compiled_res folder into an APK
65    pub fn link_compiled_res(
66        self,
67        compiled_res: Option<PathBuf>,
68        output_apk: &Path,
69        manifest: &Path,
70    ) -> Aapt2Link {
71        Aapt2Link::new_from_compiled_res(compiled_res, output_apk, manifest)
72    }
73
74    /// Used for printing information about the APK you generated using the link command
75    pub fn dump(self, subcommand: SubCommand, filename_apk: &Path) -> Aapt2Dump {
76        Aapt2Dump::new(subcommand, filename_apk)
77    }
78
79    /// Prints the differences in resources of two APKs
80    pub fn diff(self, file: &[PathBuf]) -> Aapt2Diff {
81        Aapt2Diff::new(file)
82    }
83
84    /// Preforms resource optimizations on an APK
85    pub fn optimize(self, output_apk: &Path, output_dir: &Path) -> Aapt2Optimize {
86        Aapt2Optimize::new(output_apk, output_dir)
87    }
88
89    /// Converts an apk between binary and proto formats
90    pub fn convert(self, o: &Path) -> Aapt2Convert {
91        Aapt2Convert::new(o)
92    }
93
94    /// Prints the version of aapt2
95    pub fn version(self, version: String) -> Aapt2Version {
96        Aapt2Version::new(version)
97    }
98
99    /// Runs aapt in daemon mode. Each subsequent line is a single parameter to the
100    /// command. The end of an invocation is signaled by providing an empty line
101    pub fn daemon(self, trace_folder: &Path) -> Aapt2Daemon {
102        Aapt2Daemon::new(trace_folder)
103    }
104}
105
106/// Find aapt2 executable binary file in SDK and initialize it
107pub fn aapt2_tool() -> Result<Command> {
108    if let Ok(aapt2) = which::which(bin!("aapt2")) {
109        return Ok(Command::new(aapt2));
110    }
111    let sdk_path = sdk_path_from_env()?;
112    let build_tools = sdk_path.join("build-tools");
113    let target_sdk_version = find_max_version(&build_tools)?;
114    let aapt2_exe = build_tools.join(target_sdk_version).join(bin!("aapt2"));
115    Ok(Command::new(aapt2_exe))
116}