diff --git a/src/Client/Microsoft.Maui.Client.UnitTests/AndroidProviderTests.cs b/src/Client/Microsoft.Maui.Client.UnitTests/AndroidProviderTests.cs index 74d542fd..c53f8b0f 100644 --- a/src/Client/Microsoft.Maui.Client.UnitTests/AndroidProviderTests.cs +++ b/src/Client/Microsoft.Maui.Client.UnitTests/AndroidProviderTests.cs @@ -184,6 +184,25 @@ public async Task InstallPackagesAsync_InstallsMultiplePackages() Assert.Contains("platforms;android-35", installedPackages); } + [Fact] + public async Task InstallPackagesAsync_InvokesOnProgressForEachPackage() + { + // Arrange + var provider = new FakeAndroidProvider(); + var packages = new[] { "platform-tools", "build-tools;35.0.0", "platforms;android-35" }; + var progressCalls = new List<(string pkg, int idx, int total)>(); + + // Act + await provider.InstallPackagesAsync(packages, acceptLicenses: true, + onProgress: (pkg, idx, total) => progressCalls.Add((pkg, idx, total))); + + // Assert + Assert.Equal(3, progressCalls.Count); + Assert.Equal(("platform-tools", 1, 3), progressCalls[0]); + Assert.Equal(("build-tools;35.0.0", 2, 3), progressCalls[1]); + Assert.Equal(("platforms;android-35", 3, 3), progressCalls[2]); + } + [Fact] public async Task GetAvailablePackagesAsync_ReturnsAvailablePackages() { diff --git a/src/Client/Microsoft.Maui.Client.UnitTests/Fakes/FakeAndroidProvider.cs b/src/Client/Microsoft.Maui.Client.UnitTests/Fakes/FakeAndroidProvider.cs index 81f29b9c..2ca5a766 100644 --- a/src/Client/Microsoft.Maui.Client.UnitTests/Fakes/FakeAndroidProvider.cs +++ b/src/Client/Microsoft.Maui.Client.UnitTests/Fakes/FakeAndroidProvider.cs @@ -125,7 +125,13 @@ public Task InstallPackagesAsync(IEnumerable packages, bool acceptLicens public Task InstallPackagesAsync(IEnumerable packages, bool acceptLicenses, Action? onProgress, CancellationToken cancellationToken = default) { - InstalledPackageSets.Add(packages.ToList()); + var pkgList = packages.ToList(); + InstalledPackageSets.Add(pkgList); + if (onProgress is not null) + { + for (var i = 0; i < pkgList.Count; i++) + onProgress(pkgList[i], i + 1, pkgList.Count); + } return Task.CompletedTask; } diff --git a/src/Client/Microsoft.Maui.Client/Providers/Android/SdkManager.cs b/src/Client/Microsoft.Maui.Client/Providers/Android/SdkManager.cs index 276c27f9..8c86638c 100644 --- a/src/Client/Microsoft.Maui.Client/Providers/Android/SdkManager.cs +++ b/src/Client/Microsoft.Maui.Client/Providers/Android/SdkManager.cs @@ -106,9 +106,24 @@ public async Task InstallPackagesAsync(IEnumerable packages, bool accept SyncPaths(); EnsureAvailable(); + var packageList = packages.ToList(); + try { - await _sdkManager.InstallAsync(packages, acceptLicenses, cancellationToken); + if (onProgress is null) + { + await _sdkManager.InstallAsync(packageList, acceptLicenses, cancellationToken); + } + else + { + // Install one at a time so we can report per-package progress + for (var i = 0; i < packageList.Count; i++) + { + cancellationToken.ThrowIfCancellationRequested(); + onProgress(packageList[i], i + 1, packageList.Count); + await _sdkManager.InstallAsync(new[] { packageList[i] }, acceptLicenses, cancellationToken); + } + } } catch (Exception ex) when (ex is not OperationCanceledException) {