1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
mod compile;
mod convert;
mod daemon;
mod diff;
mod dump;
mod link;
mod optimize;
mod version;
pub use compile::*;
pub use convert::*;
pub use daemon::*;
pub use diff::*;
pub use dump::*;
pub use link::*;
pub use optimize::*;
pub use version::*;
use self::{daemon::Aapt2Daemon, diff::Aapt2Diff, version::Aapt2Version};
use crate::error::*;
use std::{
path::{Path, PathBuf},
process::Command,
};
#[derive(Clone, Copy)]
pub struct Aapt2;
impl Aapt2 {
pub fn compile_incremental(self, res_path: &Path, compiled_res: &Path) -> Aapt2Compile {
Aapt2Compile::new(res_path, compiled_res)
}
pub fn compile_dir(self, res_dir: &Path, compiled_res: &Path) -> Aapt2Compile {
Aapt2Compile::new_from_res_dir(res_dir, compiled_res)
}
pub fn compile_zip(self, res_zip: &Path, compiled_res: &Path) -> Aapt2Compile {
Aapt2Compile::new_from_res_zip(res_zip, compiled_res)
}
pub fn link_inputs(self, inputs: &[PathBuf], output_apk: &Path, manifest: &Path) -> Aapt2Link {
Aapt2Link::new(inputs, output_apk, manifest)
}
pub fn link_compiled_res(
self,
compiled_res: Option<PathBuf>,
output_apk: &Path,
manifest: &Path,
) -> Aapt2Link {
Aapt2Link::new_from_compiled_res(compiled_res, output_apk, manifest)
}
pub fn dump(self, subcommand: SubCommand, filename_apk: &Path) -> Aapt2Dump {
Aapt2Dump::new(subcommand, filename_apk)
}
pub fn diff(self, file: &[PathBuf]) -> Aapt2Diff {
Aapt2Diff::new(file)
}
pub fn optimize(self, output_apk: &Path, output_dir: &Path) -> Aapt2Optimize {
Aapt2Optimize::new(output_apk, output_dir)
}
pub fn convert(self, o: &Path) -> Aapt2Convert {
Aapt2Convert::new(o)
}
pub fn version(self, version: String) -> Aapt2Version {
Aapt2Version::new(version)
}
pub fn daemon(self, trace_folder: &Path) -> Aapt2Daemon {
Aapt2Daemon::new(trace_folder)
}
}
pub fn aapt2_tool() -> Result<Command> {
if let Ok(aapt2) = which::which(bin!("aapt2")) {
return Ok(Command::new(aapt2));
}
let sdk_path = {
let sdk_path = std::env::var("ANDROID_SDK_ROOT")
.ok()
.or_else(|| std::env::var("ANDROID_SDK_PATH").ok())
.or_else(|| std::env::var("ANDROID_HOME").ok());
PathBuf::from(sdk_path.ok_or(AndroidError::AndroidSdkNotFound)?)
};
let build_tools = sdk_path.join("build-tools");
let target_sdk_version = std::fs::read_dir(&build_tools)
.map_err(|_| Error::PathNotFound(build_tools.clone()))?
.filter_map(|path| path.ok())
.filter(|path| path.path().is_dir())
.filter_map(|path| path.file_name().into_string().ok())
.filter(|name| name.chars().next().unwrap().is_digit(10))
.max()
.ok_or(AndroidError::BuildToolsNotFound)?;
let aapt2_exe = build_tools.join(target_sdk_version).join(bin!("aapt2"));
Ok(Command::new(aapt2_exe))
}