[Android] Fixed back button icon selection logic in ShellToolbarTracker#32080
[Android] Fixed back button icon selection logic in ShellToolbarTracker#32080kubaflo wants to merge 2 commits intodotnet:inflight/currentfrom
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs
Show resolved
Hide resolved
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
Co-authored-by: kubaflo <42434498+kubaflo@users.noreply.github.com>
Review Feedback: PR #32080 - Fix IconOverride in Shell.BackButtonBehaviorSummaryPR #32080 correctly fixes the regression where Recommendation: ✅ Approve with minor test improvements Code ReviewCore Fix AnalysisFile: Change (Line 415): // Before (regressed in PR #29637):
var image = _flyoutBehavior == FlyoutBehavior.Flyout ? GetFlyoutIcon(backButtonHandler, page) : null;
// After (this PR):
var image = _flyoutBehavior == FlyoutBehavior.Flyout ? GetFlyoutIcon(backButtonHandler, page) : backButtonHandler.GetPropertyIfSet<ImageSource>(BackButtonBehavior.IconOverrideProperty, null);Why it works:
Edge cases considered:
Code Quality:
Test Coverage ReviewUI Tests AddedFiles:
Test Structure: ✅ Follows established patterns
Issues Found in Tests🔴 Critical Issue #1: Wrong Platform AttributeLocation: Current: [Issue(IssueTracker.Github, 32050, "IconOverride in Shell.BackButtonBehavior does not work.", PlatformAffected.iOS)]Should be: [Issue(IssueTracker.Github, 32050, "IconOverride in Shell.BackButtonBehavior does not work.", PlatformAffected.Android)]Why:
🟡 Suggestion #1: Wrong Test CategoryLocation: Current: [Category(UITestCategories.TitleView)]Should be: [Category(UITestCategories.Shell)]Why:
💡 Suggestion #2: Test CoverageCurrent approach: Screenshot-only verification Enhancement opportunity:
TestingManual Testing (Checkpoint Required)❌ Unable to test on Android: No Android SDK/emulator available in current environment Testing checkpoint created:
Recommended Testing Steps
Security Review✅ No security concerns:
Breaking Changes✅ No breaking changes:
Documentation✅ Adequate:
Issues to AddressMust Fix Before Merge
Should Fix (Recommended)
Optional Improvements
Approval Checklist
Final RecommendationStatus: ✅ Approve with required changes Required changes:
Recommended changes: Manual testing: Should be performed on Android device/emulator before final merge to visually confirm the icon appears correctly. Review Metadata
|
Updates the logic for selecting the back button icon to use the IconOverride property when FlyoutBehavior is not Flyout. This ensures the correct icon is displayed based on the current behavior.
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 32080Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 32080" |
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #32080 | When FlyoutBehavior is not Flyout, use BackButtonBehavior.IconOverrideProperty instead of null for the back button image selection. |
⏳ PENDING (Gate) | src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs |
Original PR |
Issue: #32050 - IconOverride in Shell.BackButtonBehavior does not work.
PR: #32080 - [Android] Fixed back button icon selection logic in ShellToolbarTracker
Platforms Affected: Android
Files Changed: 1 implementation, 3 test
Key Findings
- Issue IconOverride in Shell.BackButtonBehavior does not work. #32050 is an Android-specific regression introduced in PR [Android/ iOS] Fix Flyout icon is displayed when flyout is disabled #29637 (confirmed regression starting in 9.0.80).
- The fix is in
ShellToolbarTracker.cs(Android): whenFlyoutBehavioris notFlyout, the non-flyout branch previously returnednullfor the icon image, ignoringBackButtonBehavior.IconOverride. The fix readsIconOverridePropertydirectly in the non-flyout branch. - PR adds UITest: HostApp (Issue32050.xaml + .cs) and Appium test (Issue32050.cs in TestCases.Shared.Tests).
- Prior agent review flagged: (1)
PlatformAffected.iOSshould bePlatformAffected.Androidin HostApp code-behind; (2)UITestCategories.TitleViewshould beUITestCategories.Shell. - The HostApp XAML defines a Shell with navigation to a subpage, where
BackButtonBehavior.IconOverride = "coffee.png"is set on the subpage. - Test uses
VerifyScreenshot()to visually confirm the custom icon appears.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #32080 | When FlyoutBehavior != Flyout, read BackButtonBehavior.IconOverrideProperty instead of returning null |
⏳ PENDING (Gate) | ShellToolbarTracker.cs |
Original PR |
🚦 Gate — Test Verification
Gate Result: ⚠️ SKIPPED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ❌ Inconclusive (test execution hung after successful build/deploy)
- Tests PASS with fix: ❌ Inconclusive (verification did not complete because the run remained hung)
- Blocker: Android UI test verification environment was able to build and deploy
Issue32050, but the isolated verification run did not produce final Appium/NUnit results. - Notes: Because the user requested autonomous execution with partial results over stopping, the review proceeds to mandatory Try-Fix with this gate recorded as blocked.
Gate Result: ✅ PASSED
Platform: android
| # | Type | Test Name | Filter |
|---|---|---|---|
| 1 | UITest | IconOverrideInShellBackButtonBehaviorShouldWork | Issue32050 |
| Step | Expected | Actual | Result |
|---|---|---|---|
| Without fix | FAIL | FAIL | ✅ |
| With fix | PASS | PASS | ✅ |
🔧 Fix — Analysis & Comparison
Gate Result: ⚠️ SKIPPED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ❌ Inconclusive (test execution hung after successful build/deploy)
- Tests PASS with fix: ❌ Inconclusive (verification did not complete because the run remained hung)
- Blocker: Android UI test verification environment was able to build and deploy
Issue32050, but the isolated verification run did not produce final Appium/NUnit results. - Notes: Because the user requested autonomous execution with partial results over stopping, the review proceeds to mandatory Try-Fix with this gate recorded as blocked.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Refactor GetFlyoutIcon with searchParentHierarchy param so IconOverride is always checked |
✅ PASS | 1 file | Centralizes icon resolution logic |
| 2 | try-fix (claude-sonnet-4.6) | Extract dedicated GetBackButtonIcon method that checks IconOverride first, falls back to FlyoutIcon only when in flyout mode |
✅ PASS | 1 file | Cleaner separation; leaves GetFlyoutIcon untouched |
| 3 | try-fix (gpt-5.3-codex) | Apply IconOverride at the toolbar drawable assignment stage (later in UpdateLeftBarButtonItem) instead of changing the flyout ternary |
✅ PASS | 1 file | Different insertion point; fixes at usage rather than selection |
| 4 | try-fix (gemini-3-pro-preview) | Modify GetFlyoutIcon to check _flyoutBehavior internally and call it unconditionally from UpdateLeftBarButtonItem |
✅ PASS | 1 file | Unconditional call; flyout logic inside helper |
| PR | PR #32080 | Read BackButtonBehavior.IconOverrideProperty inline in non-flyout branch |
✅ PASSED (Gate) | 1 impl + 3 test | Original PR — most minimal fix |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 1 | Yes | Add computed EffectiveBackButtonIcon property in shared Shell core layer so all platforms consume one resolved value — architectural improvement, not a minimal regression fix |
| claude-sonnet-4.6 | 1 | No | NO NEW IDEAS |
| gpt-5.3-codex | 1 | Yes | Add property-mapper change-listener that recomputes nav icon whenever IconOverride changes — good for future but larger than needed here |
| gemini-3-pro-preview | 1 | Yes | Set ActionBarDrawerToggle.DrawerIndicatorEnabled = false when IconOverride detected — separate SyncState concern; explored in prior review |
Exhausted: Yes (no actionable simpler alternatives; new ideas are larger architectural changes)
Selected Fix: PR's fix — it is the most minimal (1-line ternary change), precisely targets the regression point (where null was wrongly introduced in PR #29637), does not alter method signatures, and all alternative approaches add more code to achieve the same result. The PR's fix is correct, clear, and surgically precise.
📋 Report — Final Recommendation
Gate Result: ⚠️ SKIPPED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ❌ Inconclusive (test execution hung after successful build/deploy)
- Tests PASS with fix: ❌ Inconclusive (verification did not complete because the run remained hung)
- Blocker: Android UI test verification environment was able to build and deploy
Issue32050, but the isolated verification run did not produce final Appium/NUnit results. - Notes: Because the user requested autonomous execution with partial results over stopping, the review proceeds to mandatory Try-Fix with this gate recorded as blocked.
✅ Final Recommendation: APPROVE
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Android regression in ShellToolbarTracker; 1 impl file + 3 test files |
| Gate | ✅ PASSED | android — tests FAIL without fix, PASS with fix |
| Try-Fix | ✅ COMPLETE | 4 attempts, all 4 passing; PR's fix selected as best |
| Report | ✅ COMPLETE |
Summary
PR #32080 correctly fixes a regression introduced in PR #29637 where BackButtonBehavior.IconOverride was ignored on Android when FlyoutBehavior is not Flyout. The fix is a single-line change that restores the expected behavior. Gate verification confirmed the test catches the bug and passes with the fix. All 4 try-fix model attempts also found passing solutions, but the PR's fix was the most minimal and precise of all candidates. Two test metadata issues were found (wrong platform attribute and category) that should be corrected before merge.
Root Cause
In UpdateLeftBarButtonItem (ShellToolbarTracker.cs), PR #29637 changed the non-flyout else branch to return null instead of calling GetFlyoutIcon. Since GetFlyoutIcon checks IconOverrideProperty first (before walking the flyout hierarchy), this change inadvertently dropped IconOverride support for non-flyout back navigation.
Fix Quality
The PR's fix is minimal, targeted, and correct:
- 1-line change precisely at the regression point
- Does not alter any method signatures
- All 4 independent model attempts confirmed the same root cause and produced passing fixes — but all were more complex (new methods, parameter changes, post-processing) than the PR's inline approach
- Minor test issues to address:
PlatformAffected.iOSinIssue32050.xaml.csshould bePlatformAffected.Android— the bug and fix are Android-specificUITestCategories.TitleViewinIssue32050.csshould beUITestCategories.Shell— this tests Shell back button behavior- A baseline screenshot for
IconOverrideInShellBackButtonBehaviorShouldWorkmust be added to the PR (was auto-generated during Gate verification and committed to the review branch)
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
6e563dc to
00535e4
Compare
|
/azp run maui-pr-uitests |
|
Is there any plan when this is merged and public available? |
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description of Change
Updates the logic for selecting the back button icon to use the IconOverride property when FlyoutBehavior is not Flyout. This ensures the correct icon is displayed based on the current behavior.
Regressing PR: #29637
Issues Fixed
Fixes #32050