gplay_client/
devices.rs

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}