Preserve explicit AndroidSdkHome when directory doesn't exist yet - #91
Merged
Merged
Conversation
When a user specifies an explicit AndroidSdkHome directory (e.g. for Acquire/DownloadSdk), the SdkLocator.Locate() call discards it because PathLocator only returns paths where Directory.Exists() is true. This causes AndroidSdkHome to be null or resolve to a different SDK, making Acquire() fail with: 'Android SDK Directory was not specified.' Honor the explicitly provided path directly instead of passing it through Locate(). Only auto-discover via SdkLocator when no path is specified. Also remove the redundant re-assignment in the obsolete SdkTool(DirectoryInfo?) constructor which was overwriting the result from the delegated SdkToolOptions constructor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dalexsoto
force-pushed
the
fix/preserve-explicit-sdk-home
branch
from
March 27, 2026 20:24
38e134b to
6bdd0e0
Compare
Redth
approved these changes
Mar 29, 2026
dalexsoto
added a commit
to Redth/MAUI.Sherpa
that referenced
this pull request
Mar 31, 2026
## Problem The Doctor's 'Fix: Android SDK' action failed with: 'Android SDK Directory was not specified.' Even after fixing the upstream AndroidSdk.Tools library (PR #91), a second issue remained: after successfully acquiring the SDK to ~/android-sdk, restarting the app caused the Doctor to pick up ~/.android instead — a user config directory, not an SDK installation. ## Root Cause Two bugs contributed to the broken experience: ### 1. Upstream: SdkLocator discarded non-existent paths (fixed in AndroidSdk 0.35.1) AndroidSdkManager and SdkTool constructors passed the user-specified target directory through SdkLocator.Locate(), which only returns paths where Directory.Exists() is true. When acquiring a fresh SDK, the target directory doesn't exist yet, so: - Locate() discarded the user's path - It returned either null or a different directory (e.g. ~/.android) - DownloadSdk() then threw because it had no valid target This was fixed upstream in Redth/AndroidSdk.Tools#91 and released in AndroidSdk 0.35.1. ### 2. Local: Acquired SDK path was never persisted After AcquireSdkAsync successfully installed the SDK to ~/android-sdk: - The in-memory _sdkManager was updated correctly - SdkPathChanged event was NOT fired (missing invoke) - The path was NOT saved to secure storage On app restart, AndroidSdkSettingsService.InitializeAsync() found no saved custom path and fell back to DetectSdkAsync(), which auto- discovered ~/.android (a config directory created during the fix process) instead of ~/android-sdk (the actual SDK installation). ## Changes ### AndroidSdkService.cs - Fire SdkPathChanged event after successful SDK acquisition so that listeners (device watchers, UI pages) are notified immediately ### DoctorService.cs - Accept optional IAndroidSdkSettingsService via constructor injection - After a successful 'install-android-sdk' fix action, persist the acquired SDK path via SetCustomSdkPathAsync() so it survives app restarts and is not overridden by auto-detection ### MauiSherpa.Core.csproj - Update AndroidSdk from 0.33.0 to 0.35.1 (includes upstream fix) - Update AndroidSdk.Adbd from 0.33.0 to 0.35.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dalexsoto
added a commit
to Redth/MAUI.Sherpa
that referenced
this pull request
Mar 31, 2026
## Problem The Doctor's 'Fix: Android SDK' action failed with: 'Android SDK Directory was not specified.' Even after fixing the upstream AndroidSdk.Tools library (PR #91), a second issue remained: after successfully acquiring the SDK to ~/android-sdk, restarting the app caused the Doctor to pick up ~/.android instead — a user config directory, not an SDK installation. ## Root Cause Two bugs contributed to the broken experience: ### 1. Upstream: SdkLocator discarded non-existent paths (fixed in AndroidSdk 0.35.1) AndroidSdkManager and SdkTool constructors passed the user-specified target directory through SdkLocator.Locate(), which only returns paths where Directory.Exists() is true. When acquiring a fresh SDK, the target directory doesn't exist yet, so: - Locate() discarded the user's path - It returned either null or a different directory (e.g. ~/.android) - DownloadSdk() then threw because it had no valid target This was fixed upstream in Redth/AndroidSdk.Tools#91 and released in AndroidSdk 0.35.1. ### 2. Local: Acquired SDK path was never persisted After AcquireSdkAsync successfully installed the SDK to ~/android-sdk: - The in-memory _sdkManager was updated correctly - SdkPathChanged event was NOT fired (missing invoke) - The path was NOT saved to secure storage On app restart, AndroidSdkSettingsService.InitializeAsync() found no saved custom path and fell back to DetectSdkAsync(), which auto- discovered ~/.android (a config directory created during the fix process) instead of ~/android-sdk (the actual SDK installation). ## Changes ### AndroidSdkService.cs - Fire SdkPathChanged event after successful SDK acquisition so that listeners (device watchers, UI pages) are notified immediately ### DoctorService.cs - Accept optional IAndroidSdkSettingsService via constructor injection - After a successful 'install-android-sdk' fix action, persist the acquired SDK path via SetCustomSdkPathAsync() so it survives app restarts and is not overridden by auto-detection ### MauiSherpa.Core.csproj - Update AndroidSdk from 0.33.0 to 0.35.1 (includes upstream fix) - Update AndroidSdk.Adbd from 0.33.0 to 0.35.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced May 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When calling
AndroidSdkManager.Acquire()orSdkManager.DownloadSdk()with a target directory that doesn't exist yet (the typical fresh-install scenario), the operation fails with:Root Cause
Both
SdkToolandAndroidSdkManagerconstructors pass the user-specified path throughSdkLocator.Locate(), which only returns paths whereDirectory.Exists()is true. When the target directory doesn't exist yet:Locate()discards the user's path~/.android)AndroidSdkHomeasnullDownloadSdk()then throws because it has no target directoryFix
When a path is explicitly provided via
SdkToolOptions.AndroidSdkHomeor theAndroidSdkManager(DirectoryInfo)constructor, honor it directly instead of passing it throughLocate(). Auto-discovery viaSdkLocatoris only used when no path is specified.Also removes a redundant re-assignment in the obsolete
SdkTool(DirectoryInfo?)constructor that was overwriting the result from the delegated constructor.Tests
Added
SdkTool_PreserveHome_Testswith 6 tests covering:SdkManagerpreserves home when directory doesn't existAndroidSdkManagerpreserves home when directory doesn't existDownloadSdkdoesn't throw "not specified" for non-existent directory