1use std::{borrow::Cow};
2use gplay_protobuf::{AndroidBuildProto, AndroidCheckinProto, DeviceConfigurationProto, DeviceFeature};
3use ini::Ini;
4
5#[derive(Debug, Clone)]
6pub struct Device {
7 pub build_id: Cow<'static, str>,
8 pub build_version_release: Cow<'static, str>,
9 pub build_fingerprint: Option<Cow<'static, str>>,
10 pub build_hardware: Option<Cow<'static, str>>,
11 pub build_brand: Option<Cow<'static, str>>,
12 pub build_radio: Option<Cow<'static, str>>,
13 pub build_bootloader: Option<Cow<'static, str>>,
14 pub build_device: Option<Cow<'static, str>>,
15 pub build_version_sdk_int: Option<i32>,
16 pub build_model: Option<Cow<'static, str>>,
17 pub build_manufacturer: Option<Cow<'static, str>>,
18 pub build_product: Option<Cow<'static, str>>,
19 pub vending_version_string: Cow<'static, str>,
20 pub vending_version: Cow<'static, str>,
21 pub gsf_version: Option<i32>,
22 pub client: Option<Cow<'static, str>>,
23 pub cell_operator: Option<Cow<'static, str>>,
24 pub sim_operator: Option<Cow<'static, str>>,
25 pub roaming: Option<Cow<'static, str>>,
26 pub touchscreen: Option<i32>,
27 pub keyboard: Option<i32>,
28 pub navigation: Option<i32>,
29 pub screen_layout: Option<i32>,
30 pub has_hard_keyboard: Option<bool>,
31 pub has_five_way_navigation: Option<bool>,
32 pub shared_libraries: Cow<'static, [Cow<'static, str>]>,
33 pub features: Cow<'static, [Cow<'static, str>]>,
34 pub platforms: Cow<'static, [Cow<'static, str>]>,
35 pub locales: Cow<'static, [Cow<'static, str>]>,
36 pub screen_density: Option<i32>,
37 pub screen_width: Option<i32>,
38 pub screen_height: Option<i32>,
39 pub gl_version: Option<i32>,
40 pub gl_extensions: Cow<'static, [Cow<'static, str>]>,
41}
42
43impl Device {
44 pub fn with_architectures(mut self, architectures: &[&str]) -> Self {
45 self.platforms = architectures
46 .iter()
47 .map(|s| s.to_string().into())
48 .collect();
49 self
50 }
51
52 pub fn with_density(mut self, density: i32) -> Self {
53 self.screen_density = Some(density);
54 self
55 }
56
57 pub(crate) fn checkin(&self) -> AndroidCheckinProto {
58 AndroidCheckinProto {
59 build: Some(self.build()),
60 last_checkin_msec: Some(0),
61 cell_operator: self.cell_operator.as_ref().map(|v| v.to_string()),
62 sim_operator: self.sim_operator.as_ref().map(|v| v.to_string()),
63 roaming: self.roaming.as_ref().map(|v| v.to_string()),
64 user_number: Some(0),
65 ..Default::default()
66 }
67 }
68
69 fn build(&self) -> AndroidBuildProto {
70 AndroidBuildProto {
71 id: self.build_fingerprint.as_ref().map(|v| v.to_string()),
72 product: self.build_hardware.as_ref().map(|v| v.to_string()),
73 carrier: self.build_brand.as_ref().map(|v| v.to_string()),
74 radio: self.build_radio.as_ref().map(|v| v.to_string()),
75 bootloader: self.build_bootloader.as_ref().map(|v| v.to_string()),
76 device: self.build_device.as_ref().map(|v| v.to_string()),
77 sdk_version: self.build_version_sdk_int,
78 model: self.build_model.as_ref().map(|v| v.to_string()),
79 manufacturer: self.build_manufacturer.as_ref().map(|v| v.to_string()),
80 build_product: self.build_product.as_ref().map(|v| v.to_string()),
81 client: self.client.as_ref().map(|v| v.to_string()),
82 ota_installed: Some(false),
83 google_services: self.gsf_version,
84 ..Default::default()
85 }
86 }
87
88 pub(crate) fn configuration(&self) -> DeviceConfigurationProto {
89 DeviceConfigurationProto {
90 touch_screen: self.touchscreen,
91 keyboard: self.keyboard,
92 navigation: self.navigation,
93 screen_layout: self.screen_layout,
94 has_hard_keyboard: self.has_hard_keyboard,
95 has_five_way_navigation: self.has_five_way_navigation,
96 screen_density: self.screen_density,
97 gl_es_version: self.gl_version,
98 system_shared_library: self.shared_libraries.iter().map(|v| v.to_string()).collect(),
99 system_available_feature: self.features.iter().map(|v| v.to_string()).collect(),
100 native_platform: self.platforms.iter().map(|v| v.to_string()).collect(),
101 screen_width: self.screen_width,
102 screen_height: self.screen_height,
103 system_supported_locale: self.locales.iter().map(|v| v.to_string()).collect(),
104 gl_extension: self.gl_extensions.iter().map(|v| v.to_string()).collect(),
105 device_feature: self.features.iter().map(|v| DeviceFeature { name: Some(v.to_string()), value: Some(0) }).collect(),
106 ..Default::default()
107 }
108 }
109}
110
111pub fn parse_aurora(string: &str) -> Device {
112 let mut config = Ini::load_from_str(string).unwrap();
113 let section = config.with_general_section();
114
115 let build_id = section
116 .get("Build.ID")
117 .map(|v| v.to_owned())
118 .unwrap_or_default()
119 .into();
120 let vending_version_string = section
121 .get("Vending.versionString")
122 .map(|v| v.to_owned())
123 .unwrap_or_default()
124 .into();
125 let vending_version = section
126 .get("Vending.version")
127 .map(|v| v.to_owned())
128 .unwrap_or_default()
129 .into();
130 let build_version_release = section
131 .get("Build.VERSION.RELEASE")
132 .map(|v| v.to_owned())
133 .unwrap_or_default()
134 .into();
135 let sim_operator = section
136 .get("SimOperator")
137 .map(|v| v.to_owned().into());
138 let build_fingerprint = section
139 .get("Build.FINGERPRINT")
140 .map(|v| v.to_owned().into());
141 let build_hardware = section
142 .get("Build.HARDWARE")
143 .map(|v| v.to_owned().into());
144 let build_brand = section
145 .get("Build.BRAND")
146 .map(|v| v.to_owned().into());
147 let build_radio = section
148 .get("Build.RADIO")
149 .map(|v| v.to_owned().into());
150 let build_bootloader = section
151 .get("Build.BOOTLOADER")
152 .map(|v| v.to_owned().into());
153 let build_device = section
154 .get("Build.DEVICE")
155 .map(|v| v.to_owned().into());
156 let build_version_sdk_int = section
157 .get("Build.VERSION.SDK_INT")
158 .map(|v| v.parse().unwrap());
159 let build_model = section
160 .get("Build.MODEL")
161 .map(|v| v.to_owned().into());
162 let build_manufacturer = section
163 .get("Build.MANUFACTURER")
164 .map(|v| v.to_owned().into());
165 let build_product = section
166 .get("Build.PRODUCT")
167 .map(|v| v.to_owned().into());
168 let client = section
169 .get("Client")
170 .map(|v| v.to_owned().into());
171 let gsf_version = section
172 .get("GSF.version")
173 .map(|v| v.parse().unwrap());
174 let cell_operator = section
175 .get("CellOperator")
176 .map(|v| v.to_owned().into());
177 let roaming = section
178 .get("Roaming")
179 .map(|v| v.to_owned().into());
180 let touchscreen = section
181 .get("TouchScreen")
182 .map(|v| v.parse().unwrap());
183 let keyboard = section
184 .get("Keyboard")
185 .map(|v| v.parse().unwrap());
186 let navigation = section
187 .get("Navigation")
188 .map(|v| v.parse().unwrap());
189 let screen_layout = section
190 .get("ScreenLayout")
191 .map(|v| v.parse().unwrap());
192 let has_hard_keyboard = section
193 .get("HasHardKeyboard")
194 .map(|v| v.parse().unwrap());
195 let has_five_way_navigation = section
196 .get("HasFiveWayNavigation")
197 .map(|v| v.parse().unwrap());
198 let screen_density = section
199 .get("Screen.Density")
200 .map(|v| v.parse().unwrap());
201 let gl_version = section
202 .get("GL.Version")
203 .map(|v| v.parse().unwrap());
204 let shared_libraries = section
205 .get("SharedLibraries").unwrap()
206 .split(",")
207 .map(|s| s.to_owned().into())
208 .collect();
209 let platforms = section
210 .get("Platforms").unwrap_or_default()
211 .split(",")
212 .map(|s| s.to_owned().into())
213 .collect();
214 let screen_width = section
215 .get("Screen.Width")
216 .map(|v| v.parse().unwrap());
217 let screen_height = section
218 .get("Screen.Height")
219 .map(|v| v.parse().unwrap());
220 let locales = section
221 .get("Locales").unwrap()
222 .split(",")
223 .map(|s| s.to_owned().into())
224 .collect();
225 let gl_extensions = section
226 .get("GL.Extensions").unwrap()
227 .split(",")
228 .map(|s| s.to_owned().into())
229 .collect();
230 let features = section
231 .get("Features").unwrap()
232 .split(",")
233 .map(|s| s.to_owned().into())
234 .collect();
235
236 Device {
237 build_id,
238 build_version_release,
239 build_fingerprint,
240 build_hardware,
241 build_brand,
242 build_radio,
243 build_bootloader,
244 build_device,
245 build_version_sdk_int,
246 build_model,
247 build_manufacturer,
248 build_product,
249 vending_version_string,
250 vending_version,
251 gsf_version,
252 client,
253 cell_operator,
254 sim_operator,
255 roaming,
256 touchscreen,
257 keyboard,
258 navigation,
259 screen_layout,
260 has_hard_keyboard,
261 has_five_way_navigation,
262 shared_libraries,
263 features,
264 platforms,
265 locales,
266 screen_density,
267 screen_width,
268 screen_height,
269 gl_version,
270 gl_extensions,
271 }
272}