Skip to content

Commit dc63d66

Browse files
authored
Changes in Android cake to fix emulator boot issues on Linux (dotnet#29123)
* Apply changes to wait until verify y ADB keys have been regenerated * More comments * Fix error * More changes * More changes * Added retry (max 3 times) to push adb keys to the device * More changes
1 parent b398b9a commit dc63d66

File tree

1 file changed

+132
-22
lines changed

1 file changed

+132
-22
lines changed

eng/devices/android.cake

+132-22
Original file line numberDiff line numberDiff line change
@@ -648,47 +648,157 @@ void EnsureAdbKeys(AdbToolSettings settings)
648648

649649
try
650650
{
651-
var adbKeyPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".android");
651+
// Kill ADB server first before modifying keys
652+
Information("Stopping ADB server...");
653+
AdbKillServer(settings);
654+
System.Threading.Thread.Sleep(1000);
655+
656+
// Set up file paths
657+
var homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
658+
var adbKeyPath = System.IO.Path.Combine(homeDir, ".android");
652659
var adbKeyFile = System.IO.Path.Combine(adbKeyPath, "adbkey");
653660
var adbKeyPubFile = System.IO.Path.Combine(adbKeyPath, "adbkey.pub");
654661

662+
// Ensure ADB directory exists with correct permissions
663+
Information("Ensuring ADB key directory exists...");
664+
if (!System.IO.Directory.Exists(adbKeyPath))
665+
{
666+
System.IO.Directory.CreateDirectory(adbKeyPath);
667+
Information($"Created ADB directory at {adbKeyPath}");
668+
}
669+
670+
// Set proper directory permissions
671+
StartProcess("chmod", $"700 {adbKeyPath}");
672+
655673
// Delete existing ADB keys to avoid stale data
656-
if (System.IO.File.Exists(adbKeyFile)) System.IO.File.Delete(adbKeyFile);
657-
if (System.IO.File.Exists(adbKeyPubFile)) System.IO.File.Delete(adbKeyPubFile);
674+
Information("Cleaning up old ADB keys...");
675+
if (System.IO.File.Exists(adbKeyFile))
676+
{
677+
System.IO.File.Delete(adbKeyFile);
678+
Information("Removed existing private key");
679+
}
658680

659-
// Restart ADB to regenerate keys
660-
AdbKillServer(settings);
661-
AdbStartServer(settings);
681+
if (System.IO.File.Exists(adbKeyPubFile))
682+
{
683+
System.IO.File.Delete(adbKeyPubFile);
684+
Information("Removed existing public key");
685+
}
662686

663-
// Verify ADB keys exist
687+
// Generate new ADB keys instead of waiting for automatic generation
688+
Information("Explicitly generating new ADB keys...");
689+
StartProcess("adb", new ProcessSettings {
690+
Arguments = "keygen " + adbKeyPath,
691+
RedirectStandardOutput = true,
692+
RedirectStandardError = true
693+
});
694+
695+
// Check if keys were created
664696
if (!System.IO.File.Exists(adbKeyFile) || !System.IO.File.Exists(adbKeyPubFile))
665697
{
666-
throw new Exception("Failed to regenerate ADB keys.");
698+
throw new Exception("Failed to generate ADB keys.");
667699
}
668700

669-
Information($"ADB keys have been successfully regenerated at {adbKeyPath}.");
670-
671-
// Set correct permissions for ADB keys
672-
Information("Set correct permissions for ADB keys.");
673-
StartProcess("chmod", $"700 {adbKeyPath}");
701+
// Set correct file permissions for ADB keys
702+
Information("Setting correct permissions for ADB keys...");
674703
StartProcess("chmod", $"600 {adbKeyFile}");
675704
StartProcess("chmod", $"600 {adbKeyPubFile}");
676705

677-
// Manually authorize the emulator
678-
Information("Manually authorize the emulator with the generated ADB keys.");
679-
AdbShell("adb push ~/.android/adbkey.pub /data/misc/adb/adb_keys", settings);
680-
AdbShell("adb shell chmod 600 /data/misc/adb/adb_keys", settings);
681-
AdbShell("adb shell stop adbd", settings);
682-
AdbShell("adb shell start adbd", settings);
706+
// Set environment variable properly (platform specific)
707+
Information("Setting ADB_VENDOR_KEYS environment variable...");
683708

684-
Information("Emulator authorized successfully.");
709+
// This actually sets it for the current process
710+
SetEnvironmentVariable("ADB_VENDOR_KEYS", adbKeyPubFile);
711+
712+
// Set ADB_VENDOR_KEYS environment variable
713+
StartProcess("sh", new ProcessSettings {
714+
Arguments = new ProcessArgumentBuilder()
715+
.Append("-c")
716+
.AppendQuoted($"export ADB_VENDOR_KEYS={adbKeyPubFile}"),
717+
RedirectStandardOutput = true
718+
});
719+
720+
// Start ADB server with new keys
721+
Information("Starting ADB server with new keys...");
722+
AdbStartServer(settings);
723+
System.Threading.Thread.Sleep(2000); // Give ADB time to fully start
724+
725+
// Push keys to the device with better error handling
726+
Information("Pushing ADB keys to the device...");
727+
int retries = 0;
728+
bool pushSuccess = false;
729+
730+
while (retries < 3 && !pushSuccess)
731+
{
732+
var processSettings = new ProcessSettings {
733+
Arguments = new ProcessArgumentBuilder()
734+
.Append("push")
735+
.AppendQuoted(adbKeyPubFile)
736+
.AppendQuoted("/data/misc/adb/adb_keys"),
737+
RedirectStandardOutput = true,
738+
RedirectStandardError = true
739+
};
740+
741+
var exitCode = StartProcess("adb", processSettings);
742+
743+
// Check exit code for success indicators
744+
if (exitCode == 0)
745+
{
746+
Information("ADB key successfully pushed.");
747+
pushSuccess = true;
748+
break;
749+
}
750+
751+
retries++;
752+
Information($"Push attempt {retries} failed. Retrying in 1 second...");
753+
System.Threading.Thread.Sleep(1000);
754+
}
755+
756+
if (!pushSuccess)
757+
{
758+
throw new Exception("Failed to push ADB keys after multiple attempts.");
759+
}
760+
761+
// Set proper permissions on the device key file
762+
AdbShell("chmod 600 /data/misc/adb/adb_keys", settings);
763+
764+
// Restart ADB on device to apply changes
765+
Information("Restarting ADB daemon on the device...");
766+
AdbShell("stop adbd", settings);
767+
System.Threading.Thread.Sleep(2000);
768+
AdbShell("start adbd", settings);
769+
System.Threading.Thread.Sleep(2000);
770+
771+
// Verify connectivity after all changes
772+
var deviceCheck = StartProcess("adb", new ProcessSettings {
773+
Arguments = "devices",
774+
RedirectStandardOutput = true
775+
});
776+
777+
if (deviceCheck == 0)
778+
{
779+
Information("Device connection authorized successfully.");
780+
}
781+
else
782+
{
783+
Warning("Device may not be properly authorized. Check 'adb devices' output.");
784+
}
685785
}
686786
catch (Exception ex)
687787
{
688788
Warning($"Error ensuring ADB keys: {ex.Message}");
689-
690789
Information("Trying to restart ADB just in case...");
691790

692-
AdbKillServer(adbSettings);
791+
try
792+
{
793+
AdbKillServer(settings);
794+
System.Threading.Thread.Sleep(1000);
795+
AdbStartServer(settings);
796+
}
797+
catch (Exception innerEx)
798+
{
799+
Error($"Recovery attempt also failed: {innerEx.Message}");
800+
}
801+
802+
throw; // Re-throw the original exception
693803
}
694804
}

0 commit comments

Comments
 (0)