Fix Android grouped CollectionView header/footer rebind leak#35368
Conversation
Updated [Magick.NET-Q8-AnyCPU](https://github.com/dlemstra/Magick.NET) from 14.10.4 to 14.12.0. <details> <summary>Release notes</summary> _Sourced from [Magick.NET-Q8-AnyCPU's releases](https://github.com/dlemstra/Magick.NET/releases)._ ## 14.12.0 ### What's Changed - Added `FixByteOrder` to the `DcmReadDefines` (#1976) - Added `IconWriteDefines`. ### Related changes in ImageMagick since the last release of Magick.NET: - Correct bug in `Composite` when using `CopyAlpha` (#1985) - Fixed incorrect orientation of JPEG compressed TIFF images (#1991) - Heap-Buffer-Overflow write of single zero byte when parsing xml (GHSA-cr67-pvmx-2pp2) - Stack Overflow in DestroyXMLTree (GHSA-fwvm-ggf6-2p4x) - Out-of-Bounds read in sample operation (GHSA-pcvx-ph33-r5vv) - Stack Overflow via Recursive FX Expression Parsing (GHSA-f4qm-vj5j-9xpw) - Heap Buffer Overflow in ImageMagick MVG decoder (GHSA-x9h5-r9v2-vcww) - Heap overflow caused by integer overflow/wraparound in viff encoder on 32-bit builds (GHSA-v67w-737x-v2c9) - Stack-buffer-overflow in MNG encoder with oversized pallete (GHSA-98cp-rj9f-6v5g) - Integer overflow in despeckle operation causes heap buffer overflow on 32-bit builds (GHSA-26qp-ffjh-2x4v) - Off-by-One in MSL decoder could result in crash (GHSA-5xg3-585r-9jh5) - Heap buffer overflow when encoding JXL image with a 16-bit float (GHSA-jvgr-9ph5-m8v4) - Heap-use-after-free via XMP profile could result in a crash when printing the values (GHSA-r83h-crwp-3vm7) - Heap buffer overflow (WRITE) in the YAML and JSON encoders (GHSA-5592-p365-24xh) - Heap out-of-bounds write in JP2 encoder (GHSA-pwg5-6jfc-crvh) ### Library updates: - ImageMagick 7.1.2-19 (2026-04-12) - aom 3.13.3 (2026-04-02) - openexr 3.4.9 (2026-04-03) - freetype 2.14.3 (2026-03-22) - gdk-pixbuf 2.44.6 (2026-03-31) - harfbuzz 14.0.0 (2026-04-01) - liblzma 5.8.3 (2026-04-31) - libpng 1.6.56 (2026-03-25) **Full Changelog**: dlemstra/Magick.NET@14.11.1...14.12.0 ## 14.11.1 ### Related changes in ImageMagick since the last release of Magick.NET: - Stack-buffer-overflow WRITE in InterpretImageFilename due to overflow (GHSA-8793-7xv6-82cf) ### Library updates: - ImageMagick 7.1.2-18 (2026-03-23) - aom 3.13.2 (2026-03-19) - openexr 3.4.7 (2026-03-15) - harfbuzz 13.2.1 (2026-03-19) **Full Changelog**: dlemstra/Magick.NET@14.11.0...14.11.1 ## 14.11.0 ### What's Changed - Added `DcmReadDefines`. ### Related changes in ImageMagick since the last release of Magick.NET: - Access mode change for files created from 0666 to 0600 (ImageMagick/ImageMagick#8609) - Heap-buffer-overflow in NewXMLTree could result in crash (GHSA-gc62-2v5p-qpmp) ### Library updates: - ImageMagick 7.1.2-17 (2026-03-16) - openexr 3.4.6 (2026-03-01) - freetype 2.14.2 (2026-03-01) - harfbuzz 13.0.1 (2026-03-07) - libxml2 2.15.2 (2026-03-03) **Full Changelog**: dlemstra/Magick.NET@14.10.4...14.11.0 Commits viewable in [compare view](dlemstra/Magick.NET@14.10.4...14.12.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/dotnet/maui/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…t#35333) Bump OpenTelemetry packages to latest stable versions in the maui-aspire-servicedefaults template: - OpenTelemetry.Exporter.OpenTelemetryProtocol: 1.9.0 to 1.15.3 - OpenTelemetry.Extensions.Hosting: 1.9.0 to 1.15.3 - OpenTelemetry.Instrumentation.Http: 1.9.0 to 1.15.1 - OpenTelemetry.Instrumentation.Runtime: 1.9.0 to 1.15.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This pull request updates the following dependencies [marker]: <> (Begin:a71c12d9-5aa4-4b46-e2d6-08da0cf8cd95) ## From https://github.com/dotnet/xharness - **Subscription**: [a71c12d9-5aa4-4b46-e2d6-08da0cf8cd95](https://maestro.dot.net/subscriptions?search=a71c12d9-5aa4-4b46-e2d6-08da0cf8cd95) - **Build**: [20260430.4](https://dev.azure.com/dnceng/internal/_build/results?buildId=2964906) ([312724](https://maestro.dot.net/channel/2/github:dotnet:xharness/build/312724)) - **Date Produced**: May 1, 2026 7:05:11 AM UTC - **Commit**: [92962e5c46ac08a66ded4c5696209cc60f1a232f](dotnet/xharness@92962e5) - **Branch**: [main](https://github.com/dotnet/xharness/tree/main) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [11.0.0-prerelease.26229.1 to 11.0.0-prerelease.26230.4][1] - Microsoft.DotNet.XHarness.CLI - Microsoft.DotNet.XHarness.TestRunners.Common - Microsoft.DotNet.XHarness.TestRunners.Xunit [1]: dotnet/xharness@9d5a7e9...92962e5 [DependencyUpdate]: <> (End) [marker]: <> (End:a71c12d9-5aa4-4b46-e2d6-08da0cf8cd95) Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
> [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Replaces `review-rules.md` (flat 345-line checklist) with a dimensional expert review agent. Single source of truth for all review rules, organized into 30 dimensions for per-dimension sub-agent evaluation. Adds inline file:line PR comments alongside the existing wall-of-text summary. Extracted from 28k review comments across 5 maintainers via [extraction-pipeline](https://github.com/dotnet/fsharp/blob/main/.github/agents/extraction-pipeline.md). No functional code changes. Recreated from dotnet#35062 on a dotnet/maui branch (originally opened from a fork). ## What changed **Before:** `review-rules.md` had 345 lines of flat rules. `code-review` skill loaded them all into one context. Output was a single wall-of-text PR comment. **After:** Rules absorbed into `maui-expert-reviewer.md` as 30 dimensions with 200+ CHECK items. Each dimension runs as an independent sub-agent with focused context. Output is inline file:line PR comments via `inline-findings.json`. ## CI Flow ``` Review-PR.ps1 prompt: 1. code-review → maui-expert-reviewer agent → inline-findings.json 2. pr-review → Pre-Flight → Try-Fix → Report (sees findings, no duplication) Posting: post-inline-review.ps1 → .json → GitHub file:line comments (NEW) post-ai-summary-comment.ps1 → {phase}/content.md → wall-of-text (existing) CI: COMMENTS_VIA_FILE=true → agent writes .json, script posts Local: agent writes .json, code-review posts directly via gh api ``` ## Files | Action | File | What | |--------|------|------| | **Add** | `agents/maui-expert-reviewer.md` | 30 dimensions, 200+ CHECKs, routing table | | **Add** | `instructions/collectionview-{android,ios,windows}` | Platform-isolated CV rules | | **Add** | `instructions/{handler-patterns,layout-system,performance-hotpaths,public-api,threading-async}` | Domain-specific ambient guidance | | **Add** | `scripts/post-inline-review.ps1` | Posts .json as GitHub PR review | | **Del** | `skills/code-review/references/review-rules.md` | Absorbed into agent | | **Mod** | `skills/code-review/SKILL.md` | Delegates to agent | | **Mod** | `scripts/Review-PR.ps1` | Prompt + inline posting wiring | | **Mod** | `eng/pipelines/ci-copilot.yml` | `COMMENTS_VIA_FILE` env var | --------- Co-authored-by: kubaflo <kubaflo@users.noreply.github.com> Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tomas Grosup <tomasgrosup@microsoft.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35368Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35368" |
|
Hey there @@AdamEssenmacher! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
@dotnet-policy-service agree |
There was a problem hiding this comment.
Pull request overview
Fixes an Android grouped CollectionView leak caused by group header/footer view holders being bound twice in GroupableItemsViewAdapter.OnBindViewHolder, which could append duplicate logical-child references over repeated recycle/rebind cycles.
Changes:
- Make group header/footer binding in
GroupableItemsViewAdapter.OnBindViewHolderterminal by returning immediately afterBindTemplatedItemViewHolder(...). - Add Android device regression tests to ensure grouped header/footer recycle+rebind does not increase
CollectionViewlogical children.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Handlers/Items/Android/Adapters/GroupableItemsViewAdapter.cs | Prevents falling through to the base bind path for grouped header/footer view holders (avoids double-bind). |
| src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Android.cs | Adds regression coverage ensuring grouped header/footer rebinding doesn’t grow LogicalChildren. |
|
/azp run maui-pr |
|
Azure Pipelines successfully started running 1 pipeline(s). |
🤖 AI Summary
📊 Review Session —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📱 CollectionViewTests (GroupHeaderRebindDoesNotGrowLogicalChildren, GroupFooterRebindDoesNotGrowLogicalChildren) Category=CollectionView |
✅ FAIL — 1004s | ✅ PASS — 384s |
🔴 Without fix — 📱 CollectionViewTests (GroupHeaderRebindDoesNotGrowLogicalChildren, GroupFooterRebindDoesNotGrowLogicalChildren): FAIL ✅ · 1004s
(truncated to last 15,000 chars)
.dll.so
[41/133] Xamarin.AndroidX.DrawerLayout.dll -> Xamarin.AndroidX.DrawerLayout.dll.so
[42/133] Xamarin.AndroidX.Fragment.dll -> Xamarin.AndroidX.Fragment.dll.so
[119/133] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
[43/133] Xamarin.AndroidX.Lifecycle.Common.Jvm.dll -> Xamarin.AndroidX.Lifecycle.Common.Jvm.dll.so
[120/133] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
[121/133] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
[44/133] Xamarin.AndroidX.Lifecycle.LiveData.Core.dll -> Xamarin.AndroidX.Lifecycle.LiveData.Core.dll.so
[122/133] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
[45/133] Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll.so
[123/133] System.Text.Json.dll -> System.Text.Json.dll.so
[124/133] System.Threading.dll -> System.Threading.dll.so
[125/133] System.Xml.Linq.dll -> System.Xml.Linq.dll.so
[46/133] Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll.so
[126/133] System.Xml.ReaderWriter.dll -> System.Xml.ReaderWriter.dll.so
[127/133] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
[47/133] Xamarin.AndroidX.Loader.dll -> Xamarin.AndroidX.Loader.dll.so
[128/133] System.dll -> System.dll.so
[129/133] netstandard.dll -> netstandard.dll.so
[48/133] Xamarin.AndroidX.Navigation.Common.Android.dll -> Xamarin.AndroidX.Navigation.Common.Android.dll.so
[130/133] Mono.Android.Runtime.dll -> Mono.Android.Runtime.dll.so
[49/133] Xamarin.AndroidX.Navigation.Fragment.dll -> Xamarin.AndroidX.Navigation.Fragment.dll.so
[50/133] Xamarin.AndroidX.Navigation.Runtime.Android.dll -> Xamarin.AndroidX.Navigation.Runtime.Android.dll.so
[131/133] Java.Interop.dll -> Java.Interop.dll.so
[51/133] Xamarin.AndroidX.Navigation.UI.dll -> Xamarin.AndroidX.Navigation.UI.dll.so
[52/133] Xamarin.AndroidX.RecyclerView.dll -> Xamarin.AndroidX.RecyclerView.dll.so
[53/133] Xamarin.AndroidX.SavedState.SavedState.Android.dll -> Xamarin.AndroidX.SavedState.SavedState.Android.dll.so
[54/133] Xamarin.AndroidX.SwipeRefreshLayout.dll -> Xamarin.AndroidX.SwipeRefreshLayout.dll.so
[55/133] Xamarin.AndroidX.ViewPager.dll -> Xamarin.AndroidX.ViewPager.dll.so
[56/133] Xamarin.AndroidX.ViewPager2.dll -> Xamarin.AndroidX.ViewPager2.dll.so
[57/133] Xamarin.Google.Android.Material.dll -> Xamarin.Google.Android.Material.dll.so
[58/133] Xamarin.GooglePlayServices.Base.dll -> Xamarin.GooglePlayServices.Base.dll.so
[132/133] Mono.Android.dll -> Mono.Android.dll.so
[59/133] Xamarin.GooglePlayServices.Basement.dll -> Xamarin.GooglePlayServices.Basement.dll.so
[60/133] Xamarin.GooglePlayServices.Maps.dll -> Xamarin.GooglePlayServices.Maps.dll.so
[61/133] Xamarin.GooglePlayServices.Tasks.dll -> Xamarin.GooglePlayServices.Tasks.dll.so
[62/133] Xamarin.Kotlin.StdLib.dll -> Xamarin.Kotlin.StdLib.dll.so
[63/133] Xamarin.KotlinX.Coroutines.Core.Jvm.dll -> Xamarin.KotlinX.Coroutines.Core.Jvm.dll.so
[64/133] Xamarin.KotlinX.Serialization.Core.Jvm.dll -> Xamarin.KotlinX.Serialization.Core.Jvm.dll.so
[65/133] xunit.abstractions.dll -> xunit.abstractions.dll.so
[66/133] xunit.assert.dll -> xunit.assert.dll.so
[67/133] xunit.core.dll -> xunit.core.dll.so
[68/133] xunit.execution.dotnet.dll -> xunit.execution.dotnet.dll.so
[69/133] xunit.runner.utility.netcoreapp10.dll -> xunit.runner.utility.netcoreapp10.dll.so
[70/133] System.Collections.Concurrent.dll -> System.Collections.Concurrent.dll.so
[71/133] System.Collections.Immutable.dll -> System.Collections.Immutable.dll.so
[72/133] System.Collections.NonGeneric.dll -> System.Collections.NonGeneric.dll.so
[73/133] System.Collections.Specialized.dll -> System.Collections.Specialized.dll.so
[74/133] System.Collections.dll -> System.Collections.dll.so
[133/133] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
[75/133] System.ComponentModel.Primitives.dll -> System.ComponentModel.Primitives.dll.so
[76/133] System.ComponentModel.TypeConverter.dll -> System.ComponentModel.TypeConverter.dll.so
[77/133] System.ComponentModel.dll -> System.ComponentModel.dll.so
[78/133] System.Console.dll -> System.Console.dll.so
[79/133] System.Diagnostics.Debug.dll -> System.Diagnostics.Debug.dll.so
[80/133] System.Diagnostics.DiagnosticSource.dll -> System.Diagnostics.DiagnosticSource.dll.so
[81/133] System.Diagnostics.Process.dll -> System.Diagnostics.Process.dll.so
[82/133] System.Diagnostics.Tools.dll -> System.Diagnostics.Tools.dll.so
[83/133] System.Diagnostics.TraceSource.dll -> System.Diagnostics.TraceSource.dll.so
[84/133] System.Diagnostics.Tracing.dll -> System.Diagnostics.Tracing.dll.so
[85/133] System.Drawing.Primitives.dll -> System.Drawing.Primitives.dll.so
[86/133] System.Drawing.dll -> System.Drawing.dll.so
[87/133] System.Formats.Asn1.dll -> System.Formats.Asn1.dll.so
[88/133] System.Globalization.dll -> System.Globalization.dll.so
[89/133] System.IO.Compression.Brotli.dll -> System.IO.Compression.Brotli.dll.so
[90/133] System.IO.Compression.dll -> System.IO.Compression.dll.so
[91/133] System.IO.FileSystem.dll -> System.IO.FileSystem.dll.so
[92/133] System.IO.Pipelines.dll -> System.IO.Pipelines.dll.so
[93/133] System.IO.dll -> System.IO.dll.so
[94/133] System.Linq.Expressions.dll -> System.Linq.Expressions.dll.so
[95/133] System.Linq.dll -> System.Linq.dll.so
[96/133] System.Memory.dll -> System.Memory.dll.so
[97/133] System.Net.Http.dll -> System.Net.Http.dll.so
[98/133] System.Net.NameResolution.dll -> System.Net.NameResolution.dll.so
[99/133] System.Net.Primitives.dll -> System.Net.Primitives.dll.so
[100/133] System.Net.Requests.dll -> System.Net.Requests.dll.so
[101/133] System.Net.Sockets.dll -> System.Net.Sockets.dll.so
[102/133] System.Numerics.Vectors.dll -> System.Numerics.Vectors.dll.so
[103/133] System.ObjectModel.dll -> System.ObjectModel.dll.so
[104/133] System.Private.Uri.dll -> System.Private.Uri.dll.so
[105/133] System.Private.Xml.Linq.dll -> System.Private.Xml.Linq.dll.so
[106/133] System.Private.Xml.dll -> System.Private.Xml.dll.so
[107/133] System.Reflection.Extensions.dll -> System.Reflection.Extensions.dll.so
[108/133] System.Reflection.TypeExtensions.dll -> System.Reflection.TypeExtensions.dll.so
[109/133] System.Reflection.dll -> System.Reflection.dll.so
[110/133] System.Runtime.Extensions.dll -> System.Runtime.Extensions.dll.so
[111/133] System.Runtime.InteropServices.RuntimeInformation.dll -> System.Runtime.InteropServices.RuntimeInformation.dll.so
[112/133] System.Runtime.InteropServices.dll -> System.Runtime.InteropServices.dll.so
[113/133] System.Runtime.Loader.dll -> System.Runtime.Loader.dll.so
[114/133] System.Runtime.Numerics.dll -> System.Runtime.Numerics.dll.so
[115/133] System.Runtime.dll -> System.Runtime.dll.so
[116/133] System.Security.Cryptography.dll -> System.Security.Cryptography.dll.so
[117/133] System.Text.Encoding.dll -> System.Text.Encoding.dll.so
[118/133] System.Text.Encodings.Web.dll -> System.Text.Encodings.Web.dll.so
[119/133] System.Text.Json.dll -> System.Text.Json.dll.so
[120/133] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
[121/133] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
[122/133] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
[123/133] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
[124/133] System.Threading.dll -> System.Threading.dll.so
[125/133] System.Xml.Linq.dll -> System.Xml.Linq.dll.so
[126/133] System.Xml.ReaderWriter.dll -> System.Xml.ReaderWriter.dll.so
[127/133] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
[128/133] System.dll -> System.dll.so
[129/133] netstandard.dll -> netstandard.dll.so
[130/133] Java.Interop.dll -> Java.Interop.dll.so
[131/133] Mono.Android.Runtime.dll -> Mono.Android.Runtime.dll.so
[132/133] Mono.Android.dll -> Mono.Android.dll.so
[133/133] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:11:12.61
[11.0.0-prerelease.26230.4+92962e5c46ac08a66ded4c5696209cc60f1a232f] XHarness command issued: android test --app /home/vsts/work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-android/com.microsoft.maui.controls.devicetests-Signed.apk --package-name com.microsoft.maui.controls.devicetests --device-id emulator-5554 -o artifacts/log --timeout 01:00:00 -v --arg TestFilter=Category=CollectionView
�[40m�[37mdbug�[39m�[22m�[49m: ADBRunner using ADB.exe supplied from /home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/tools/net10.0/any/../../../runtimes/any/native/adb/linux/adb
�[40m�[37mdbug�[39m�[22m�[49m: Full resolved path:'/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb'
�[40m�[32minfo�[39m�[22m�[49m: Will attempt to find device supporting architectures: 'arm64-v8a', 'x86_64'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb start-server'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[32minfo�[39m�[22m�[49m: Finding attached devices/emulators...
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb devices -l'
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 possible devices
�[40m�[37mdbug�[39m�[22m�[49m: Evaluating output line for device serial: emulator-5554 device product:sdk_gphone_x86_64 model:sdk_gphone_x86_64 device:generic_x86_64_arm64 transport_id:2
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell getprop ro.product.cpu.abilist'
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 possible devices. Using 'emulator-5554'
�[40m�[32minfo�[39m�[22m�[49m: Active Android device set to serial 'emulator-5554'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop ro.product.cpu.abi'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop ro.build.version.sdk'
�[40m�[32minfo�[39m�[22m�[49m: Waiting for device to be available (max 5 minutes)
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 wait-for-device'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop sys.boot_completed'
�[40m�[37mdbug�[39m�[22m�[49m: sys.boot_completed = '1'
�[40m�[37mdbug�[39m�[22m�[49m: Waited 0 seconds for device boot completion
�[40m�[37mdbug�[39m�[22m�[49m: Working with emulator-5554 (API 30)
�[40m�[37mdbug�[39m�[22m�[49m: Check current adb install and/or package verification settings
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell settings get global verifier_verify_adb_installs'
�[40m�[37mdbug�[39m�[22m�[49m: verifier_verify_adb_installs = 0
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell settings get global package_verifier_enable'
�[40m�[37mdbug�[39m�[22m�[49m: package_verifier_enable =
�[40m�[1m�[33mwarn�[39m�[22m�[49m: Installing debug apks on a device might be rejected with INSTALL_FAILED_VERIFICATION_FAILURE. Make sure to set 'package_verifier_enable' to '0'
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.controls.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.controls.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Waiting for command timed out: execution may be compromised
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: -2
Std out:
�[40m�[32minfo�[39m�[22m�[49m: Attempting to install /home/vsts/work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-android/com.microsoft.maui.controls.devicetests-Signed.apk
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 install /home/vsts/work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-android/com.microsoft.maui.controls.devicetests-Signed.apk'
�[41m�[30mfail�[39m�[22m�[49m: Error:
Exit code: 1
Std out:
Serving...
Performing Incremental Install
cmd: Failure calling service package: Broken pipe (32)
Performing Streamed Install
Std err:
All files should be loaded. Notifying the device.
adb: failed to install /home/vsts/work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-android/com.microsoft.maui.controls.devicetests-Signed.apk: cmd: Can't find service: package
�[41m�[1m�[37mcrit�[39m�[22m�[49m: Install failure: Test command cannot continue
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.controls.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.controls.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: 20
Std out:
Std err:
cmd: Can't find service: package
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.controls.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.controls.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: 20
Std out:
Std err:
cmd: Can't find service: package
XHarness exit code: 78 (PACKAGE_INSTALLATION_FAILURE)
Tests completed with exit code: 78
🟢 With fix — 📱 CollectionViewTests (GroupHeaderRebindDoesNotGrowLogicalChildren, GroupFooterRebindDoesNotGrowLogicalChildren): PASS ✅ · 384s
(truncated to last 15,000 chars)
17 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Element'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Entry'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'FlexLayout'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'FlyoutPage'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Frame'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Gesture'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'HybridWebView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Image'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Label'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Layout'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Lifecycle'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'ListView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Map'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'MenuFlyout'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Mapper'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Excluded test (filtered by Trait; 'Category':'Memory'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Modal'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'NavigationPage'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Page'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Path'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Picker'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'RadioButton'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'RefreshView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'ScrollView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'SearchBar'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Shape'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Shell'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Slider'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'SwipeView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'TabbedPage'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'TextInput'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Toolbar'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'TemplatedView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'View'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'VisualElement'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'VisualElementTree'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'WebView'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Window'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'WindowOverlay'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Xaml'): [Memory] BindableLayout Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Accessibility'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Application'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Behavior'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Border'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'BoxView'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Button'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'CarouselView'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'CheckBox'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Compatibility'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'ContentView'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'DatePicker'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Dispatcher'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Editor'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Element'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Entry'): [Memory] Window Does Not Leak
05-11 10:43:48.835 15717 15744 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'FlexLayout'): [Memory] Window Does Not Leak
05-11 10:43:48.862 15717 15744 I DOTNET : [Test environment: 64-bit .NET .NET 10.0 [collection-per-class, non-parallel]]
05-11 10:43:48.862 15717 15744 I DOTNET : [Test framework: xUnit.net 2.9.0.0]
05-11 10:43:48.875 15717 15744 I DOTNET : Serialize test because it has to add itself to the main window
05-11 10:43:49.020 15717 15756 I DOTNET : [PASS] CollectionView SelectionMode None → Single attaches click listeners
05-11 10:43:49.488 15717 15762 I DOTNET : [PASS] SafeAreaBehaviorConsistency
05-11 10:43:49.760 15717 15767 I DOTNET : [PASS] SafeAreaBehaviorConsistency
05-11 10:43:49.772 15717 15767 I DOTNET : [PASS] ObservableCollection modifications are reflected after UI thread processes them
05-11 10:43:49.809 15717 15767 I DOTNET : [PASS] Grouped CollectionView header rebind does not grow logical children
05-11 10:43:52.877 15717 15773 I DOTNET : [PASS] PushAndPopPageWithCollectionView
05-11 10:43:52.881 15717 15773 I DOTNET : [IGNORED] CellSizeAccountsForMargin
05-11 10:43:54.290 15717 15783 I DOTNET : [PASS] SwipeView in CollectionView does not crash
05-11 10:43:54.582 15717 15788 I DOTNET : [PASS] NullItemsSourceDisplaysHeaderFooterAndEmptyView
05-11 10:43:54.594 15717 15788 I DOTNET : [PASS] CollectionView with SnapPointsType set should not crash
05-11 10:44:07.556 15717 15890 I DOTNET : [PASS] ItemsSourceDoesNotLeak
05-11 10:44:07.561 15717 15890 I DOTNET : [PASS] CollectionView SelectionMode Single → None removes click listeners
05-11 10:44:07.572 15717 15890 I DOTNET : [PASS] Grouped CollectionView footer rebind does not grow logical children
05-11 10:44:07.576 15717 15890 I DOTNET : [PASS] CollectionView SelectionMode Single → Multiple keeps click listeners
05-11 10:44:08.299 15717 15895 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:08.954 15717 15901 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:09.662 15717 15906 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:10.335 15717 15911 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:11.032 15717 15916 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:11.755 15717 15921 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:12.503 15717 15927 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:13.222 15717 15933 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:13.997 15717 15938 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:14.686 15717 15943 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:15.380 15717 15948 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:16.138 15717 15979 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:19.820 15717 15989 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:23.421 15717 15996 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:27.152 15717 16001 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:30.926 15717 16006 I DOTNET : [PASS] CollectionViewCanSizeToContent
05-11 10:44:31.225 15717 16011 I DOTNET : [PASS] SettingSelectedItemAfterModifyingCollectionDoesntCrash
05-11 10:44:31.937 15717 16016 I DOTNET : [PASS] CollectionScrollToUngroupedWorks
05-11 10:44:32.173 15717 16021 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:32.376 15717 16026 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:32.575 15717 16031 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:32.758 15717 16036 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:32.987 15717 16041 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:33.177 15717 16046 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:33.408 15717 16051 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:33.607 15717 16056 I DOTNET : [PASS] CollectionViewStructuralItems
05-11 10:44:33.628 15717 16056 I DOTNET : [PASS] CollectionView with SelectionMode None should not have click listeners
05-11 10:44:33.824 15717 16061 I DOTNET : [PASS] CollectionViewItemsWithFixedWidthAndDifferentHeight
05-11 10:44:33.827 15717 16061 I DOTNET : [PASS] EmptySource should have a count of zero
05-11 10:44:34.571 15717 16066 I DOTNET : [PASS] CollectionScrollToGroupWorks
05-11 10:44:35.059 15717 16071 I DOTNET : [PASS] ClearingItemsSourceClearsBindingContext
05-11 10:44:35.081 15717 16071 I DOTNET : Microsoft.Maui.DeviceTests.CollectionViewTests 45.9437383 ms
05-11 10:44:35.085 15717 16071 I DOTNET : Test collection for Microsoft.Maui.DeviceTests.AlertDialogTests
05-11 10:44:35.132 15717 16071 I DOTNET : [PASS] AlertDialogButtonColorDarkTheme
05-11 10:44:35.295 15717 16071 I DOTNET : [PASS] AlertDialogButtonColorLightTheme
05-11 10:44:35.296 15717 16071 I DOTNET : Microsoft.Maui.DeviceTests.AlertDialogTests 0.2091997 ms
05-11 10:44:35.390 15717 15744 I DOTNET : Xml file was written to the provided writer.
05-11 10:44:35.391 15717 15744 I DOTNET : Tests run: 584 Passed: 46 Inconclusive: 0 Failed: 0 Ignored: 537
�[40m�[32minfo�[39m�[22m�[49m: <<XHARNESS_RESULT_START>>
{
"version": 1,
"machineName": "runnervmfz4j5",
"exitCode": 0,
"exitCodeName": "SUCCESS",
"platform": "android",
"instrumentationExitCode": 0,
"device": "emulator-5554",
"deviceOsVersion": "API 30",
"architecture": "x86_64",
"files": [
{
"name": "testResults.xml",
"type": "test-results"
},
{
"name": "adb-logcat-com.microsoft.maui.controls.devicetests-default.log",
"type": "logcat"
}
]
}
<<XHARNESS_RESULT_END>>
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.controls.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.controls.devicetests'
�[40m�[32minfo�[39m�[22m�[49m: Successfully uninstalled com.microsoft.maui.controls.devicetests
XHarness exit code: 0
Tests completed successfully
📁 Fix files reverted (1 files)
src/Controls/src/Core/Handlers/Items/Android/Adapters/GroupableItemsViewAdapter.cs
🧪 UI Tests — CollectionView
Detected UI test categories: CollectionView
🧪 UI Test Execution Results
⏭️ SKIPPED — 0 passed, 0 failed, 1 skipped (platform: android)
| Category | Result | Tests | Duration | Notes |
|---|---|---|---|---|
CollectionView |
⏭️ SKIPPED | — | 2.5s | Runner threw an exception |
Failures here are informational only — they do not block the gate or affect try-fix candidate scoring.
🔍 Pre-Flight — Context & Validation
Pre-Flight — PR #35368
PR
- Title: Fix Android grouped CollectionView header/footer rebind leak
- Author: AdamEssenmacher (community ✨)
- Base:
main@b71adea6 - Head:
issue-17698@fb72d323 - Labels: platform/android, area-controls-collectionview, community ✨
- Files changed: 2 (+78 / -2)
- Linked issue: Memory leak when scrolling a CollectionView with IsGrouped=true #17698 — "Memory leak when scrolling a CollectionView with IsGrouped=true" (Android, t/bug, perf/memory-leak 💦, Backlog milestone, reported in net8 rc.1)
Issue summary
On Android, scrolling an IsGrouped=true CollectionView grows memory unbounded (gcdumps show List size delta +144,688 between two snapshots). With IsGrouped=false memory is stable. Open since 2023-09-27.
Root cause (as identified by PR)
GroupableItemsViewAdapter.OnBindViewHolder binds grouped header/footer holders via BindTemplatedItemViewHolder(...), but the if block had no return. Execution then fell through to base.OnBindViewHolder (chain SelectableItemsViewAdapter → StructuredItemsViewAdapter → ItemsViewAdapter). The ItemsViewAdapter.OnBindViewHolder switch matches TemplatedItemViewHolder and calls BindTemplatedItemViewHolder a second time. Each bind re-registers the rendered content into LogicalChildren without the previous one ever being torn down, so every recycle/rebind adds another entry — a permanent leak on every group header/footer recycle.
The structured (non-grouped) Header/Footer path in StructuredItemsViewAdapter.OnBindViewHolder already uses return; after BindTemplatedItemViewHolder, so the fix is to apply the same pattern to grouped headers/footers.
Diff (essence)
// GroupableItemsViewAdapter.cs : OnBindViewHolder
if (holder is TemplatedItemViewHolder templatedItemViewHolder &&
(ItemsSource.IsGroupFooter(position) || ItemsSource.IsGroupHeader(position)))
{
BindTemplatedItemViewHolder(templatedItemViewHolder, ItemsSource.GetItem(position));
+ return;
}
base.OnBindViewHolder(holder, position);Plus two Android device tests in CollectionViewTests.Android.cs:
GroupHeaderRebindDoesNotGrowLogicalChildren— 5 recycle/bind cycles at position 0, assertsLogicalChildren.Countis constant.GroupFooterRebindDoesNotGrowLogicalChildren— same pattern at the footer position withGroupFooterTemplate.
Risk surface
- Surgical, single-line behavior change confined to grouped header/footer binding path on Android.
- No public API change.
PublicAPI.Unshipped.txtuntouched. - Does NOT touch iOS, Windows, or items2 paths.
- Tests use the existing
LayoutAndGetViewHolderhelper and follow the file's established patterns.
Gate
✅ PASSED (per provided gate result) — added tests fail without the fix and pass with it. Not re-run here.
Conclusion for downstream phases
The PR is small, targeted, and consistent with existing patterns elsewhere in the same family of adapters. Try-fix alternatives should explore (a) reverse direction (teardown in OnViewRecycled), (b) idempotent bind in TemplatedItemViewHolder, (c) early bail-out at base level, and (d) handler-detection / inheritance concerns.
🔧 Fix — Analysis & Comparison
Try-Fix Aggregate — PR #35368
Four independent fix alternatives were explored against main (base b71adea6), each loading domain knowledge from a different maui-expert-reviewer dimension. All four were rejected in favor of the PR's existing fix.
| Candidate | Dimension | Approach | Verdict |
|---|---|---|---|
| try-fix-1 | handler-patterns | Gate the double-bind in ItemsViewAdapter (base) |
❌ Wrong abstraction level (base doesn't know about groups); broader regression surface |
| try-fix-2 | performance-hotpaths | Make TemplatedItemViewHolder.Bind idempotent re: LogicalChildren |
❌ Hides the real defect (redundant template Bind still runs); adds per-cell Contains overhead |
| try-fix-3 | collectionview-android | if/else instead of early return |
❌ Stylistic only; pr's guard+return matches StructuredItemsViewAdapter already |
| try-fix-4 | handler-lifecycle | Teardown in OnViewRecycled; allow double-bind |
❌ Doesn't cleanly pass the new test; performance regression (forces template recreate per scroll) |
The PR's fix (+ return; after BindTemplatedItemViewHolder for grouped header/footer) is:
- minimal (one line),
- consistent with the existing pattern in
StructuredItemsViewAdapter.OnBindViewHolder, - correct at the correct call site (the subclass that already performed the bind),
- and accompanied by two well-scoped Android device regression tests that the gate confirms fail without the fix and pass with it.
No try-fix candidate exceeds the PR's fix on any axis.
📋 Report — Final Recommendation
Comparative Report — PR #35368
Candidates evaluated
| Candidate | Description | Tests (gate) | Verdict |
|---|---|---|---|
| pr | The PR fix as submitted: + return; after grouped header/footer bind |
✅ PASS (gate confirmed) | ✅ Winner |
| pr-plus-reviewer | PR fix + expert-reviewer feedback applied | ✅ PASS (identical to pr) |
tie with pr |
| try-fix-1 | Base-level gate (ItemsViewAdapter) |
❌ N/A — wrong abstraction; would over-touch | rejected |
| try-fix-2 | Idempotent AddLogicalChild in TemplatedItemViewHolder.Bind |
❌ Hides redundant work; perf regression on hot path | rejected |
| try-fix-3 | if/else instead of return |
✅ Behaviorally identical to pr |
rejected (less consistent than pr) |
| try-fix-4 | Teardown in OnViewRecycled |
❌ Would NOT pass the new test cleanly | rejected (would FAIL regression tests) |
Ranking
- pr / pr-plus-reviewer (identical contents) — passes regression tests, correct level, consistent with sibling adapter.
- try-fix-3 — passes regression tests, but less consistent with surrounding code.
- try-fix-1, try-fix-2 — either over-broad or hides the actual defect; would likely fail or weaken the regression contract.
- try-fix-4 — would fail the added regression tests (duplicate
LogicalChildrenwould appear within a single bind cycle, before the nextOnViewRecycledruns).
Per task rules, candidates that fail regression tests are ranked below those that pass. try-fix-4 sits last for that reason.
Tie-break: pr vs pr-plus-reviewer
The expert review surfaced no actionable changes. The only consideration was a clarifying comment, which was deliberately not applied to match the un-commented style of the sibling StructuredItemsViewAdapter. The two candidates are byte-identical. The winner is therefore pr, with pr-plus-reviewer treated as a confirmation rather than an improvement.
Winner
pr — accept the PR as submitted.
Rationale
- One-line surgical fix at the correct call site.
- Mirrors the established pattern in
StructuredItemsViewAdapter.OnBindViewHolder. - Two Android device regression tests that cover both grouped-header and grouped-footer paths and meet the file's existing patterns.
- Gate confirmed the tests fail without the fix and pass with it.
- No public API change; no cross-platform surface impact; no perf concerns; no threading concerns.
- All explored alternatives are either equivalent (try-fix-3), broader and riskier (try-fix-1, try-fix-2), or actively worse on the regression contract (try-fix-4).
Recommendation to author
None required. PR is ready to merge once CI is green.
### Description of Change Fixes an Android grouped `CollectionView` leak where group header and footer view holders were bound twice during `OnBindViewHolder`. Grouped headers/footers already bind through `BindTemplatedItemViewHolder(...)`, but the adapter then fell through to the base binding path, causing `TemplatedItemViewHolder.Bind(...)` to run a second time and append duplicate logical-child references. This change makes grouped header/footer binding terminal, matching the existing structured header/footer adapter behavior. Added Android device regressions for both grouped headers and grouped footers to verify repeated recycle/rebind cycles do not grow `LogicalChildren`. ### Issues Fixed Fixes #17698 ---------
### Description of Change Fixes an Android grouped `CollectionView` leak where group header and footer view holders were bound twice during `OnBindViewHolder`. Grouped headers/footers already bind through `BindTemplatedItemViewHolder(...)`, but the adapter then fell through to the base binding path, causing `TemplatedItemViewHolder.Bind(...)` to run a second time and append duplicate logical-child references. This change makes grouped header/footer binding terminal, matching the existing structured header/footer adapter behavior. Added Android device regressions for both grouped headers and grouped footers to verify repeated recycle/rebind cycles do not grow `LogicalChildren`. ### Issues Fixed Fixes #17698 ---------
Description of Change
Fixes an Android grouped
CollectionViewleak where group header and footer view holders were bound twice duringOnBindViewHolder.Grouped headers/footers already bind through
BindTemplatedItemViewHolder(...), but the adapter then fell through to the base binding path, causingTemplatedItemViewHolder.Bind(...)to run a second time and append duplicate logical-child references. This change makes grouped header/footer binding terminal, matching the existing structured header/footer adapter behavior.Added Android device regressions for both grouped headers and grouped footers to verify repeated recycle/rebind cycles do not grow
LogicalChildren.Issues Fixed
Fixes #17698