android_tools_rs/aapt2/
optimize.rs

1use crate::error::*;
2use std::path::{Path, PathBuf};
3use std::process::Command;
4
5#[derive(Clone, Default)]
6pub struct Aapt2Optimize {
7    output_apk: PathBuf,
8    output_dir: PathBuf,
9    config_xml_file: Option<PathBuf>,
10    apk_artifacts: bool,
11    target_densities: Option<String>,
12    resources_config_path: Option<PathBuf>,
13    configs_to_include: Option<String>,
14    split: Option<PathBuf>,
15    keep_artifacts: Option<String>,
16    enable_sparse_encoding: bool,
17    collapse_resource_name: bool,
18    shorten_resource_paths: bool,
19    resource_path_shortening_map: Option<PathBuf>,
20    verbose: bool,
21    help: bool,
22}
23
24impl Aapt2Optimize {
25    /// Initialize struct Aapt2Diff then specifies path to the aapt2 link output APK and
26    /// Path to the output directory (for splits)
27    pub fn new(output_apk: &Path, output_dir: &Path) -> Self {
28        Self {
29            output_apk: output_apk.to_owned(),
30            output_dir: output_dir.to_owned(),
31            ..Default::default()
32        }
33    }
34
35    /// Specifies path to XML configuration file
36    pub fn config_xml_file(&mut self, config_xml_file: &Path) -> &mut Self {
37        self.config_xml_file = Some(config_xml_file.to_owned());
38        self
39    }
40
41    /// Print the multi APK artifacts and exit.
42    pub fn apk_artifacts(&mut self, apk_artifacts: bool) -> &mut Self {
43        self.apk_artifacts = apk_artifacts;
44        self
45    }
46
47    /// Comma separated list of the screen densities that the APK will be optimized for.
48    /// All the resources that would be unused on devices of the given densities will be
49    /// removed from the APK
50    pub fn target_densities(&mut self, target_densities: &str) -> &mut Self {
51        self.target_densities = Some(target_densities.to_owned());
52        self
53    }
54
55    /// Path to the resources.cfg file containing the list of resources and directives to
56    /// each resource. ```Format: type/resource_name#[directive][,directive]```
57    pub fn resources_config_path(&mut self, resources_config_path: &Path) -> &mut Self {
58        self.resources_config_path = Some(resources_config_path.to_owned());
59        self
60    }
61
62    /// Comma separated list of configurations to include. The default is all
63    /// configurations
64    pub fn configs_to_include(&mut self, configs_to_include: &str) -> &mut Self {
65        self.configs_to_include = Some(configs_to_include.to_owned());
66        self
67    }
68
69    /// Split resources matching a set of configs out to a Split APK.
70    /// ```Syntax: path/to/output.apk;<config>[,<config>[...]].```
71    /// On Windows, use a semicolon ';' separator instead
72    pub fn split(&mut self, split: &Path) -> &mut Self {
73        self.split = Some(split.to_owned());
74        self
75    }
76
77    /// Comma separated list of artifacts to keep.
78    /// If none are specified, all artifacts will be kept
79    pub fn keep_artifacts(&mut self, keep_artifacts: &str) -> &mut Self {
80        self.keep_artifacts = Some(keep_artifacts.to_owned());
81        self
82    }
83
84    /// Enables encoding sparse entries using a binary search tree. This decreases APK
85    /// size at the cost of resource retrieval performance
86    pub fn enable_sparse_encoding(&mut self, enable_sparse_encoding: bool) -> &mut Self {
87        self.enable_sparse_encoding = enable_sparse_encoding;
88        self
89    }
90
91    /// Collapses resource names to a single value in the key string pool.
92    /// Resources can be exempted using the "no_collapse" directive in a file specified by
93    /// --resources-config-path
94    pub fn collapse_resource_name(&mut self, collapse_resource_name: bool) -> &mut Self {
95        self.collapse_resource_name = collapse_resource_name;
96        self
97    }
98
99    /// Shortens the paths of resources inside the APK
100    pub fn shorten_resource_paths(&mut self, shorten_resource_paths: bool) -> &mut Self {
101        self.shorten_resource_paths = shorten_resource_paths;
102        self
103    }
104
105    /// Path to output the map of old resource paths to shortened paths
106    pub fn resource_path_shortening_map(
107        &mut self,
108        resource_path_shortening_map: &Path,
109    ) -> &mut Self {
110        self.resource_path_shortening_map = Some(resource_path_shortening_map.to_owned());
111        self
112    }
113
114    /// Enables verbose logging
115    pub fn verbose(&mut self, verbose: bool) -> &mut Self {
116        self.verbose = verbose;
117        self
118    }
119
120    /// Displays this help menu
121    pub fn help(&mut self, help: bool) -> &mut Self {
122        self.help = help;
123        self
124    }
125
126    /// Opens the command line and launches aapt2 optimize with arguments
127    pub fn run(self) -> Result<()> {
128        let mut aapt2 = Command::new("aapt2");
129        aapt2.arg("optimize");
130        aapt2.arg("-o").arg(&self.output_apk);
131        aapt2.arg("-d").arg(&self.output_dir);
132        if let Some(config_xml_file) = self.config_xml_file {
133            aapt2.arg("-x").arg(config_xml_file);
134        }
135        if self.apk_artifacts {
136            aapt2.arg("-p");
137        }
138        if let Some(target_densities) = self.target_densities {
139            aapt2.arg("--target_densities").arg(target_densities);
140        }
141        if let Some(resources_config_path) = self.resources_config_path {
142            aapt2
143                .arg("--resources_config_path")
144                .arg(resources_config_path);
145        }
146        if let Some(configs_to_include) = self.configs_to_include {
147            aapt2.arg("-c").arg(configs_to_include);
148        }
149        if let Some(split) = self.split {
150            aapt2.arg("--split").arg(split);
151        }
152        if let Some(keep_artifacts) = self.keep_artifacts {
153            aapt2.arg("--keep_artifacts").arg(keep_artifacts);
154        }
155        if self.enable_sparse_encoding {
156            aapt2.arg("--enable_sparse_encoding");
157        }
158        if self.collapse_resource_name {
159            aapt2.arg("--collapse_resource_name");
160        }
161        if self.shorten_resource_paths {
162            aapt2.arg("--shorten_resource_paths");
163        }
164        if let Some(resource_path_shortening_map) = self.resource_path_shortening_map {
165            aapt2
166                .arg("--resource_path_shortening_map")
167                .arg(resource_path_shortening_map);
168        }
169        if self.verbose {
170            aapt2.arg("-v");
171        }
172        if self.help {
173            aapt2.arg("-h");
174        }
175        aapt2.output_err(true)?;
176        Ok(())
177    }
178}