More sensible defaults for CoreADI on Linux
Dadoum

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