Dadoum commited on 2026-07-10 00:14:35
Showing 4 changed files, with 114 additions and 39 deletions.
| ... | ... |
@@ -114,6 +114,7 @@ pub(crate) struct AdiPreferences {
|
| 114 | 114 |
pub(crate) android_adi_identifier: Option<String>, |
| 115 | 115 |
pub(crate) android_device: MachineIdentityPreferences, |
| 116 | 116 |
pub(crate) android_device_uuid: Option<String>, |
| 117 |
+ pub(crate) android_device_identity_customized: bool, |
|
| 117 | 118 |
#[serde(skip_serializing)] |
| 118 | 119 |
pub(crate) android_machine: MachineIdentityPreferences, |
| 119 | 120 |
} |
| ... | ... |
@@ -63,6 +63,7 @@ pub(crate) struct SideloaderState {
|
| 63 | 63 |
pub(crate) selected_adi_backend: usize, |
| 64 | 64 |
pub(crate) machine_identity: MachineIdentity, |
| 65 | 65 |
pub(crate) android_device_identity: MachineIdentity, |
| 66 |
+ pub(crate) android_device_identity_customized: bool, |
|
| 66 | 67 |
pub(crate) android_adi_identifier: String, |
| 67 | 68 |
pub(crate) enabled_patches: Vec<bool>, |
| 68 | 69 |
pub(crate) sideload_operation: SideloadOperation, |
| ... | ... |
@@ -86,11 +87,11 @@ impl SideloaderState {
|
| 86 | 87 |
.or_else(|| preferences.adi.android_device_uuid.clone()) |
| 87 | 88 |
.unwrap_or_default(); |
| 88 | 89 |
let generated_android_device_uuid = ensure_android_device_uuid(&mut android_device_uuid); |
| 89 |
- let mut android_device_identity = |
|
| 90 |
- android_device_identity_from_host(&machine_identity, android_device_uuid); |
|
| 91 |
- apply_machine_identity_preferences( |
|
| 92 |
- &mut android_device_identity, |
|
| 90 |
+ let android_device_identity_customized = preferences.adi.android_device_identity_customized; |
|
| 91 |
+ let android_device_identity = android_adi_identity( |
|
| 92 |
+ android_device_uuid, |
|
| 93 | 93 |
&preferences.adi.android_device, |
| 94 |
+ android_device_identity_customized, |
|
| 94 | 95 |
); |
| 95 | 96 |
let mut android_adi_identifier = preferences |
| 96 | 97 |
.adi |
| ... | ... |
@@ -150,6 +151,7 @@ impl SideloaderState {
|
| 150 | 151 |
selected_adi_backend, |
| 151 | 152 |
machine_identity, |
| 152 | 153 |
android_device_identity, |
| 154 |
+ android_device_identity_customized, |
|
| 153 | 155 |
android_adi_identifier, |
| 154 | 156 |
enabled_patches, |
| 155 | 157 |
sideload_operation: SideloadOperation::Idle, |
| ... | ... |
@@ -246,16 +248,36 @@ impl SideloaderState {
|
| 246 | 248 |
.filter(|backend| backend.availability.is_ready()) |
| 247 | 249 |
.map(|backend| backend.kind) |
| 248 | 250 |
.ok_or_else(|| "No ready ADI backend is available.".to_string())?; |
| 251 |
+ let machine_identity = self.adi_machine_identity(adi_backend); |
|
| 249 | 252 |
|
| 250 | 253 |
Ok(DeveloperSessionContext::new( |
| 251 | 254 |
account.id.to_string(), |
| 252 | 255 |
account.apple_id.to_string(), |
| 253 | 256 |
adi_backend, |
| 254 |
- self.machine_identity.clone(), |
|
| 257 |
+ machine_identity.clone(), |
|
| 255 | 258 |
self.android_adi_identifier.clone(), |
| 256 | 259 |
)) |
| 257 | 260 |
} |
| 258 | 261 |
|
| 262 |
+ pub(crate) fn adi_machine_identity(&self, backend: AdiBackendKind) -> &MachineIdentity {
|
|
| 263 |
+ Self::machine_identity_for_adi_backend( |
|
| 264 |
+ backend, |
|
| 265 |
+ &self.machine_identity, |
|
| 266 |
+ &self.android_device_identity, |
|
| 267 |
+ ) |
|
| 268 |
+ } |
|
| 269 |
+ |
|
| 270 |
+ pub(crate) fn machine_identity_for_adi_backend<'a>( |
|
| 271 |
+ backend: AdiBackendKind, |
|
| 272 |
+ host_identity: &'a MachineIdentity, |
|
| 273 |
+ android_identity: &'a MachineIdentity, |
|
| 274 |
+ ) -> &'a MachineIdentity {
|
|
| 275 |
+ match backend {
|
|
| 276 |
+ AdiBackendKind::AndroidCoreAdi => android_identity, |
|
| 277 |
+ AdiBackendKind::SystemAdid | AdiBackendKind::WindowsCoreAdi => host_identity, |
|
| 278 |
+ } |
|
| 279 |
+ } |
|
| 280 |
+ |
|
| 259 | 281 |
pub(crate) fn default_developer_app_id_fields( |
| 260 | 282 |
&self, |
| 261 | 283 |
team_id: &str, |
| ... | ... |
@@ -342,6 +364,7 @@ impl SideloaderState {
|
| 342 | 364 |
|
| 343 | 365 |
pub(crate) fn replace_android_device_identity(&mut self, identity: MachineIdentity) {
|
| 344 | 366 |
self.android_device_identity = identity; |
| 367 |
+ self.android_device_identity_customized = true; |
|
| 345 | 368 |
} |
| 346 | 369 |
|
| 347 | 370 |
pub(crate) fn refresh_adi_backends(&mut self) {
|
| ... | ... |
@@ -390,6 +413,7 @@ impl SideloaderState {
|
| 390 | 413 |
android_adi_identifier: Some(self.android_adi_identifier.clone()), |
| 391 | 414 |
android_device: MachineIdentityPreferences::from(&self.android_device_identity), |
| 392 | 415 |
android_device_uuid: Some(self.android_device_identity.machine_id.to_string()), |
| 416 |
+ android_device_identity_customized: self.android_device_identity_customized, |
|
| 393 | 417 |
android_machine: MachineIdentityPreferences::default(), |
| 394 | 418 |
}, |
| 395 | 419 |
} |
| ... | ... |
@@ -575,18 +599,27 @@ fn is_uuid(identifier: &str) -> bool {
|
| 575 | 599 |
uuid::Uuid::parse_str(identifier).is_ok() |
| 576 | 600 |
} |
| 577 | 601 |
|
| 578 |
-fn android_device_identity_from_host( |
|
| 579 |
- host_identity: &MachineIdentity, |
|
| 580 |
- device_uuid: String, |
|
| 581 |
-) -> MachineIdentity {
|
|
| 602 |
+fn default_android_adi_identity(device_uuid: String) -> MachineIdentity {
|
|
| 582 | 603 |
MachineIdentity {
|
| 583 |
- machine_name: host_identity.machine_name.clone(), |
|
| 584 |
- os_name: host_identity.os_name.clone(), |
|
| 585 |
- os_version: host_identity.os_version.clone(), |
|
| 604 |
+ machine_name: "MacBookPro13,2".to_string(), |
|
| 605 |
+ os_name: "macOS".to_string(), |
|
| 606 |
+ os_version: "13.1;22C65".to_string(), |
|
| 586 | 607 |
machine_id: device_uuid, |
| 587 | 608 |
} |
| 588 | 609 |
} |
| 589 | 610 |
|
| 611 |
+fn android_adi_identity( |
|
| 612 |
+ device_uuid: String, |
|
| 613 |
+ preferences: &MachineIdentityPreferences, |
|
| 614 |
+ customized: bool, |
|
| 615 |
+) -> MachineIdentity {
|
|
| 616 |
+ let mut identity = default_android_adi_identity(device_uuid); |
|
| 617 |
+ if customized {
|
|
| 618 |
+ apply_machine_identity_preferences(&mut identity, preferences); |
|
| 619 |
+ } |
|
| 620 |
+ identity |
|
| 621 |
+} |
|
| 622 |
+ |
|
| 590 | 623 |
fn apply_machine_identity_preferences( |
| 591 | 624 |
identity: &mut MachineIdentity, |
| 592 | 625 |
preferences: &MachineIdentityPreferences, |
| ... | ... |
@@ -710,6 +743,7 @@ mod tests {
|
| 710 | 743 |
selected_adi_backend: 0, |
| 711 | 744 |
machine_identity: identity.clone(), |
| 712 | 745 |
android_device_identity: identity, |
| 746 |
+ android_device_identity_customized: false, |
|
| 713 | 747 |
android_adi_identifier: "0123456789abcdef".to_string(), |
| 714 | 748 |
enabled_patches: Vec::new(), |
| 715 | 749 |
sideload_operation: SideloadOperation::Idle, |
| ... | ... |
@@ -964,24 +998,20 @@ mod tests {
|
| 964 | 998 |
|
| 965 | 999 |
#[test] |
| 966 | 1000 |
fn machine_identity_preferences_override_android_identity_fields() {
|
| 967 |
- let host_identity = MachineIdentity {
|
|
| 968 |
- machine_name: "Host".to_string(), |
|
| 969 |
- os_name: "macOS".to_string(), |
|
| 970 |
- os_version: "15.0".to_string(), |
|
| 971 |
- machine_id: "HOST-ID".to_string(), |
|
| 972 |
- }; |
|
| 973 |
- let mut android_identity = |
|
| 974 |
- android_device_identity_from_host(&host_identity, "ANDROID-ID".to_string()); |
|
| 975 |
- |
|
| 976 |
- apply_machine_identity_preferences( |
|
| 977 |
- &mut android_identity, |
|
| 978 |
- &MachineIdentityPreferences {
|
|
| 1001 |
+ let preferences = MachineIdentityPreferences {
|
|
| 979 | 1002 |
machine_name: Some("Android Device".to_string()),
|
| 980 | 1003 |
os_name: None, |
| 981 | 1004 |
os_version: Some("14".to_string()),
|
| 982 | 1005 |
machine_id: Some("PERSISTED-ID".to_string()),
|
| 983 |
- }, |
|
| 984 |
- ); |
|
| 1006 |
+ }; |
|
| 1007 |
+ let default_identity = android_adi_identity("ANDROID-ID".to_string(), &preferences, false);
|
|
| 1008 |
+ |
|
| 1009 |
+ assert_eq!(default_identity.machine_name, "MacBookPro13,2"); |
|
| 1010 |
+ assert_eq!(default_identity.os_name, "macOS"); |
|
| 1011 |
+ assert_eq!(default_identity.os_version, "13.1;22C65"); |
|
| 1012 |
+ assert_eq!(default_identity.machine_id, "ANDROID-ID"); |
|
| 1013 |
+ |
|
| 1014 |
+ let android_identity = android_adi_identity("ANDROID-ID".to_string(), &preferences, true);
|
|
| 985 | 1015 |
|
| 986 | 1016 |
assert_eq!(android_identity.machine_name, "Android Device"); |
| 987 | 1017 |
assert_eq!(android_identity.os_name, "macOS"); |
| ... | ... |
@@ -488,10 +488,13 @@ impl SettingsSnapshot {
|
| 488 | 488 |
.adi_backends |
| 489 | 489 |
.get(state.selected_adi_backend) |
| 490 | 490 |
.and_then(|backend| backend.availability.is_ready().then_some(backend.kind)); |
| 491 |
+ let machine_identity = adi_backend |
|
| 492 |
+ .map(|backend| state.adi_machine_identity(backend).clone()) |
|
| 493 |
+ .unwrap_or_else(|| state.machine_identity.clone()); |
|
| 491 | 494 |
|
| 492 | 495 |
Some(Self::DeveloperLogin(DeveloperLoginSnapshot {
|
| 493 | 496 |
adi_backend, |
| 494 |
- machine_identity: state.machine_identity.clone(), |
|
| 497 |
+ machine_identity, |
|
| 495 | 498 |
android_adi_identifier: state.android_adi_identifier.clone(), |
| 496 | 499 |
})) |
| 497 | 500 |
} |
| ... | ... |
@@ -2595,12 +2598,12 @@ impl SettingsWindow {
|
| 2595 | 2598 |
.backends |
| 2596 | 2599 |
.get(snapshot.selected_backend) |
| 2597 | 2600 |
.map(|backend| {
|
| 2598 |
- let machine_identity = match backend.kind {
|
|
| 2599 |
- AdiBackendKind::AndroidCoreAdi => snapshot.android_device_identity.clone(), |
|
| 2600 |
- AdiBackendKind::SystemAdid | AdiBackendKind::WindowsCoreAdi => {
|
|
| 2601 |
- snapshot.machine_identity.clone() |
|
| 2602 |
- } |
|
| 2603 |
- }; |
|
| 2601 |
+ let machine_identity = SideloaderState::machine_identity_for_adi_backend( |
|
| 2602 |
+ backend.kind, |
|
| 2603 |
+ &snapshot.machine_identity, |
|
| 2604 |
+ &snapshot.android_device_identity, |
|
| 2605 |
+ ) |
|
| 2606 |
+ .clone(); |
|
| 2604 | 2607 |
( |
| 2605 | 2608 |
backend.kind, |
| 2606 | 2609 |
machine_identity, |
| ... | ... |
@@ -3510,6 +3513,7 @@ mod tests {
|
| 3510 | 3513 |
selected_adi_backend: 0, |
| 3511 | 3514 |
machine_identity: sample_identity("HOST"),
|
| 3512 | 3515 |
android_device_identity: sample_identity("ANDROID"),
|
| 3516 |
+ android_device_identity_customized: false, |
|
| 3513 | 3517 |
android_adi_identifier: "0123456789abcdef".to_string(), |
| 3514 | 3518 |
enabled_patches: Vec::new(), |
| 3515 | 3519 |
sideload_operation: SideloadOperation::Idle, |
| ... | ... |
@@ -3587,6 +3591,43 @@ mod tests {
|
| 3587 | 3591 |
}; |
| 3588 | 3592 |
assert_eq!(after_app.app.name(), "Fresh"); |
| 3589 | 3593 |
} |
| 3594 |
+ |
|
| 3595 |
+ #[test] |
|
| 3596 |
+ fn developer_login_uses_the_current_adi_machine_identity() {
|
|
| 3597 |
+ let mut state = sample_state(); |
|
| 3598 |
+ |
|
| 3599 |
+ let Some(SettingsSnapshot::DeveloperLogin(android_login)) = |
|
| 3600 |
+ SettingsSnapshot::from_state(&SettingsMode::DeveloperLogin, &state) |
|
| 3601 |
+ else {
|
|
| 3602 |
+ panic!("developer login snapshot should be available");
|
|
| 3603 |
+ }; |
|
| 3604 |
+ assert_eq!( |
|
| 3605 |
+ android_login.adi_backend, |
|
| 3606 |
+ Some(AdiBackendKind::AndroidCoreAdi) |
|
| 3607 |
+ ); |
|
| 3608 |
+ assert_eq!(android_login.machine_identity.machine_id, "ANDROID"); |
|
| 3609 |
+ |
|
| 3610 |
+ state.adi_backends[0].kind = AdiBackendKind::SystemAdid; |
|
| 3611 |
+ let Some(SettingsSnapshot::DeveloperLogin(system_login)) = |
|
| 3612 |
+ SettingsSnapshot::from_state(&SettingsMode::DeveloperLogin, &state) |
|
| 3613 |
+ else {
|
|
| 3614 |
+ panic!("developer login snapshot should be available");
|
|
| 3615 |
+ }; |
|
| 3616 |
+ assert_eq!(system_login.adi_backend, Some(AdiBackendKind::SystemAdid)); |
|
| 3617 |
+ assert_eq!(system_login.machine_identity.machine_id, "HOST"); |
|
| 3618 |
+ |
|
| 3619 |
+ state.adi_backends[0].kind = AdiBackendKind::WindowsCoreAdi; |
|
| 3620 |
+ let Some(SettingsSnapshot::DeveloperLogin(windows_login)) = |
|
| 3621 |
+ SettingsSnapshot::from_state(&SettingsMode::DeveloperLogin, &state) |
|
| 3622 |
+ else {
|
|
| 3623 |
+ panic!("developer login snapshot should be available");
|
|
| 3624 |
+ }; |
|
| 3625 |
+ assert_eq!( |
|
| 3626 |
+ windows_login.adi_backend, |
|
| 3627 |
+ Some(AdiBackendKind::WindowsCoreAdi) |
|
| 3628 |
+ ); |
|
| 3629 |
+ assert_eq!(windows_login.machine_identity.machine_id, "HOST"); |
|
| 3630 |
+ } |
|
| 3590 | 3631 |
} |
| 3591 | 3632 |
|
| 3592 | 3633 |
impl Render for SettingsWindow {
|
| ... | ... |
@@ -33,12 +33,15 @@ pub(super) fn render(props: AdiViewProps<'_>, cx: &mut Context<SettingsWindow>) |
| 33 | 33 |
} = props; |
| 34 | 34 |
let selected = selected_backend.min(backends.len().saturating_sub(1)); |
| 35 | 35 |
let backend = backends.get(selected); |
| 36 |
- let displayed_machine_identity: &MachineIdentity = match backend.map(|backend| backend.kind) {
|
|
| 37 |
- Some(AdiBackendKind::AndroidCoreAdi) => android_device_identity, |
|
| 38 |
- Some(AdiBackendKind::SystemAdid) | Some(AdiBackendKind::WindowsCoreAdi) | None => {
|
|
| 39 |
- machine_identity |
|
| 40 |
- } |
|
| 41 |
- }; |
|
| 36 |
+ let displayed_machine_identity = backend |
|
| 37 |
+ .map(|backend| {
|
|
| 38 |
+ SideloaderState::machine_identity_for_adi_backend( |
|
| 39 |
+ backend.kind, |
|
| 40 |
+ machine_identity, |
|
| 41 |
+ android_device_identity, |
|
| 42 |
+ ) |
|
| 43 |
+ }) |
|
| 44 |
+ .unwrap_or(machine_identity); |
|
| 42 | 45 |
let editable_identity = backend |
| 43 | 46 |
.map(|backend| backend.editable_identity) |
| 44 | 47 |
.unwrap_or(false); |
| 45 | 48 |