Skip to content

Fix Android grouped CollectionView header/footer rebind leak#35368

Merged
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
AdamEssenmacher:issue-17698
May 12, 2026
Merged

Fix Android grouped CollectionView header/footer rebind leak#35368
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
AdamEssenmacher:issue-17698

Conversation

@AdamEssenmacher

Copy link
Copy Markdown

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

dependabot Bot and others added 5 commits May 7, 2026 08:48
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>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Magick.NET-Q8-AnyCPU&package-manager=nuget&previous-version=14.10.4&new-version=14.12.0)](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>
Copilot AI review requested due to automatic review settings May 10, 2026 23:22
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35368

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35368"

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label May 10, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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.

@AdamEssenmacher

Copy link
Copy Markdown
Author

@dotnet-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.OnBindViewHolder terminal by returning immediately after BindTemplatedItemViewHolder(...).
  • Add Android device regression tests to ensure grouped header/footer recycle+rebind does not increase CollectionView logical 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.

@jfversluis

Copy link
Copy Markdown
Member

/azp run maui-pr

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@kubaflo

kubaflo commented May 12, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Summary

👋 @AdamEssenmacher — new AI review results are available. Please review the latest session below.

📊 Review Sessionfb72d32 · Fix grouped CollectionView header footer rebind leak · 2026-05-12 09:38 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: ANDROID · Base: main · Merge base: f8cb875e

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 SelectableItemsViewAdapterStructuredItemsViewAdapterItemsViewAdapter). 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, asserts LogicalChildren.Count is constant.
  • GroupFooterRebindDoesNotGrowLogicalChildren — same pattern at the footer position with GroupFooterTemplate.

Risk surface

  • Surgical, single-line behavior change confined to grouped header/footer binding path on Android.
  • No public API change. PublicAPI.Unshipped.txt untouched.
  • Does NOT touch iOS, Windows, or items2 paths.
  • Tests use the existing LayoutAndGetViewHolder helper 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

  1. pr / pr-plus-reviewer (identical contents) — passes regression tests, correct level, consistent with sibling adapter.
  2. try-fix-3 — passes regression tests, but less consistent with surrounding code.
  3. try-fix-1, try-fix-2 — either over-broad or hides the actual defect; would likely fail or weaken the regression contract.
  4. try-fix-4 — would fail the added regression tests (duplicate LogicalChildren would appear within a single bind cycle, before the next OnViewRecycled runs).

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.


@kubaflo kubaflo changed the base branch from main to inflight/current May 12, 2026 10:21
@kubaflo kubaflo merged commit a525bed into dotnet:inflight/current May 12, 2026
30 of 35 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR7 milestone May 12, 2026
@AdamEssenmacher AdamEssenmacher deleted the issue-17698 branch May 12, 2026 18:46
PureWeen pushed a commit that referenced this pull request Jun 2, 2026
### 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

---------
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
### 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

---------
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-collectionview CollectionView, CarouselView, IndicatorView community ✨ Community Contribution platform/android

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory leak when scrolling a CollectionView with IsGrouped=true

5 participants