Skip to content

Fix Android stale ContainerView root leak - #35372

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

Fix Android stale ContainerView root leak#35372
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
AdamEssenmacher:issue-35371

Conversation

@AdamEssenmacher

Copy link
Copy Markdown
Contributor

Description of Change

Fixes an Android leak when replacing Window.Page from a FlyoutPage root with another page while the window remains active.

The old Flyout root is hosted through an Android ContainerView. During root replacement, NavigationRootManager.ClearPlatformParts() dropped _rootView without clearing the old ContainerView.CurrentView, leaving the replaced FlyoutPage graph reachable through the stale container. The fix clears CurrentView before dropping the old root view, which also clears MainView.

Added Android device coverage proving that replacing an active FlyoutPage root clears the old root ContainerView.CurrentView and MainView.

Validation:

  • Verified the new test fails before the fix with the old FlyoutPage still in CurrentView.
  • Android Window device tests passed: 16/16.
  • Android Memory category passed: 61/61.
  • Standalone repro app validated: all tracked page counts reached 0 and Weak refs alive: 0/4.

Issues Fixed

Fixes #35371

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 11, 2026 07:03
@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 -- 35372

Or

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

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label May 11, 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.

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 memory leak that could retain a replaced FlyoutPage root graph when Window.Page is swapped while the window is still active, by ensuring the old Android ContainerView is fully detached from the replaced root.

Changes:

  • Clear ContainerView.CurrentView (and thus MainView) in NavigationRootManager.ClearPlatformParts() before dropping the old _rootView.
  • Add an Android device test asserting that swapping an active FlyoutPage root clears the old ContainerView’s CurrentView and MainView.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Core/src/Platform/Android/Navigation/NavigationRootManager.cs Clears stale ContainerView.CurrentView during root cleanup to break the reference chain keeping the old page graph alive.
src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs Adds Android device coverage validating the old root ContainerView is cleared after replacing a FlyoutPage window root.

@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 changed the base branch from main to inflight/current May 11, 2026 14:56
@MauiBot

MauiBot commented May 11, 2026

Copy link
Copy Markdown
Collaborator

🤖 AI Summary

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

📊 Review Sessiondc87011 · Fix Android stale ContainerView root leak · 2026-05-11 16:46 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ❌ FAILED

Platform: ANDROID · Base: main · Merge base: 4c19ffb3

🩺 Fix does not pass the tests — every test still fails after applying the fix. The PR's change does not resolve the failure(s).

Test Without Fix (expect FAIL) With Fix (expect PASS)
📱 WindowTests (ReplacedFlyoutPageRootClearsOldContainerView) Category=Window ✅ FAIL — 515s ❌ FAIL — 1031s
🔴 Without fix — 📱 WindowTests (ReplacedFlyoutPageRootClearsOldContainerView): FAIL ✅ · 515s

(truncated to last 15,000 chars)

67/133] xunit.assert.dll -> xunit.assert.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
  [12/133] Microsoft.Maui.Controls.DeviceTests.dll -> Microsoft.Maui.Controls.DeviceTests.dll.so
  [70/133] System.Collections.Concurrent.dll -> System.Collections.Concurrent.dll.so
  [13/133] Microsoft.DotNet.XHarness.TestRunners.Common.dll -> Microsoft.DotNet.XHarness.TestRunners.Common.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
  [14/133] Microsoft.DotNet.XHarness.TestRunners.Xunit.dll -> Microsoft.DotNet.XHarness.TestRunners.Xunit.dll.so
  [74/133] System.ComponentModel.Primitives.dll -> System.ComponentModel.Primitives.dll.so
  [75/133] System.Collections.dll -> System.Collections.dll.so
  [15/133] Microsoft.Extensions.Configuration.dll -> Microsoft.Extensions.Configuration.dll.so
  [76/133] System.ComponentModel.dll -> System.ComponentModel.dll.so
  [16/133] Microsoft.Extensions.Configuration.Abstractions.dll -> Microsoft.Extensions.Configuration.Abstractions.dll.so
  [77/133] System.ComponentModel.TypeConverter.dll -> System.ComponentModel.TypeConverter.dll.so
  [17/133] Microsoft.Extensions.Configuration.Binder.dll -> Microsoft.Extensions.Configuration.Binder.dll.so
  [78/133] System.Diagnostics.Debug.dll -> System.Diagnostics.Debug.dll.so
  [79/133] System.Console.dll -> System.Console.dll.so
  [80/133] System.Diagnostics.Process.dll -> System.Diagnostics.Process.dll.so
  [18/133] Microsoft.Extensions.DependencyInjection.dll -> Microsoft.Extensions.DependencyInjection.dll.so
  [81/133] System.Diagnostics.DiagnosticSource.dll -> System.Diagnostics.DiagnosticSource.dll.so
  [82/133] System.Diagnostics.TraceSource.dll -> System.Diagnostics.TraceSource.dll.so
  [83/133] System.Diagnostics.Tools.dll -> System.Diagnostics.Tools.dll.so
  [19/133] Microsoft.Extensions.DependencyInjection.Abstractions.dll -> Microsoft.Extensions.DependencyInjection.Abstractions.dll.so
  [20/133] Microsoft.Extensions.Diagnostics.Abstractions.dll -> Microsoft.Extensions.Diagnostics.Abstractions.dll.so
  [84/133] System.Diagnostics.Tracing.dll -> System.Diagnostics.Tracing.dll.so
  [85/133] System.Drawing.Primitives.dll -> System.Drawing.Primitives.dll.so
  [21/133] Microsoft.Extensions.FileProviders.Abstractions.dll -> Microsoft.Extensions.FileProviders.Abstractions.dll.so
  [86/133] System.Drawing.dll -> System.Drawing.dll.so
  [87/133] System.Formats.Asn1.dll -> System.Formats.Asn1.dll.so
  [22/133] Microsoft.Extensions.Hosting.Abstractions.dll -> Microsoft.Extensions.Hosting.Abstractions.dll.so
  [88/133] System.Globalization.dll -> System.Globalization.dll.so
  [89/133] System.IO.Compression.Brotli.dll -> System.IO.Compression.Brotli.dll.so
  [23/133] Microsoft.Extensions.Logging.dll -> Microsoft.Extensions.Logging.dll.so
  [90/133] System.IO.Compression.dll -> System.IO.Compression.dll.so
  [91/133] System.IO.FileSystem.dll -> System.IO.FileSystem.dll.so
  [24/133] Microsoft.Extensions.Logging.Abstractions.dll -> Microsoft.Extensions.Logging.Abstractions.dll.so
  [92/133] System.IO.dll -> System.IO.dll.so
  [93/133] System.IO.Pipelines.dll -> System.IO.Pipelines.dll.so
  [25/133] Microsoft.Extensions.Logging.Configuration.dll -> Microsoft.Extensions.Logging.Configuration.dll.so
  [26/133] Microsoft.Extensions.Logging.Console.dll -> Microsoft.Extensions.Logging.Console.dll.so
  [27/133] Microsoft.Extensions.Options.dll -> Microsoft.Extensions.Options.dll.so
  [28/133] Microsoft.Extensions.Options.ConfigurationExtensions.dll -> Microsoft.Extensions.Options.ConfigurationExtensions.dll.so
  [94/133] System.Linq.Expressions.dll -> System.Linq.Expressions.dll.so
  [29/133] Microsoft.Extensions.Primitives.dll -> Microsoft.Extensions.Primitives.dll.so
  [95/133] System.Memory.dll -> System.Memory.dll.so
  [30/133] Mono.Options.dll -> Mono.Options.dll.so
  [96/133] System.Linq.dll -> System.Linq.dll.so
  [31/133] Xamarin.AndroidX.Activity.dll -> Xamarin.AndroidX.Activity.dll.so
  [97/133] System.Net.NameResolution.dll -> System.Net.NameResolution.dll.so
  [98/133] System.Net.Http.dll -> System.Net.Http.dll.so
  [32/133] Xamarin.AndroidX.AppCompat.dll -> Xamarin.AndroidX.AppCompat.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
  [33/133] Xamarin.AndroidX.AppCompat.AppCompatResources.dll -> Xamarin.AndroidX.AppCompat.AppCompatResources.dll.so
  [102/133] System.Numerics.Vectors.dll -> System.Numerics.Vectors.dll.so
  [34/133] Xamarin.AndroidX.Browser.dll -> Xamarin.AndroidX.Browser.dll.so
  [103/133] System.ObjectModel.dll -> System.ObjectModel.dll.so
  [104/133] System.Private.Uri.dll -> System.Private.Uri.dll.so
  [35/133] Xamarin.AndroidX.CardView.dll -> Xamarin.AndroidX.CardView.dll.so
  [105/133] System.Private.Xml.Linq.dll -> System.Private.Xml.Linq.dll.so
  [106/133] System.Reflection.Extensions.dll -> System.Reflection.Extensions.dll.so
  [36/133] Xamarin.AndroidX.Collection.Jvm.dll -> Xamarin.AndroidX.Collection.Jvm.dll.so
  [107/133] System.Private.Xml.dll -> System.Private.Xml.dll.so
  [108/133] System.Reflection.TypeExtensions.dll -> System.Reflection.TypeExtensions.dll.so
  [37/133] Xamarin.AndroidX.CoordinatorLayout.dll -> Xamarin.AndroidX.CoordinatorLayout.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
  [38/133] Xamarin.AndroidX.Core.dll -> Xamarin.AndroidX.Core.dll.so
  [112/133] System.Runtime.InteropServices.dll -> System.Runtime.InteropServices.dll.so
  [113/133] System.Runtime.Loader.dll -> System.Runtime.Loader.dll.so
  [39/133] Xamarin.AndroidX.CursorAdapter.dll -> Xamarin.AndroidX.CursorAdapter.dll.so
  [114/133] System.Runtime.dll -> System.Runtime.dll.so
  [40/133] Xamarin.AndroidX.CustomView.dll -> Xamarin.AndroidX.CustomView.dll.so
  [115/133] System.Runtime.Numerics.dll -> System.Runtime.Numerics.dll.so
  [116/133] System.Text.Encoding.dll -> System.Text.Encoding.dll.so
  [41/133] Xamarin.AndroidX.DrawerLayout.dll -> Xamarin.AndroidX.DrawerLayout.dll.so
  [117/133] System.Security.Cryptography.dll -> System.Security.Cryptography.dll.so
  [118/133] System.Text.Encodings.Web.dll -> System.Text.Encodings.Web.dll.so
  [42/133] Xamarin.AndroidX.Fragment.dll -> Xamarin.AndroidX.Fragment.dll.so
  [43/133] Xamarin.AndroidX.Lifecycle.Common.Jvm.dll -> Xamarin.AndroidX.Lifecycle.Common.Jvm.dll.so
  [44/133] Xamarin.AndroidX.Lifecycle.LiveData.Core.dll -> Xamarin.AndroidX.Lifecycle.LiveData.Core.dll.so
  [45/133] Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll.so
  [119/133] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
  [120/133] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
  [121/133] System.Text.Json.dll -> System.Text.Json.dll.so
  [46/133] Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll.so
  [122/133] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
  [123/133] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
  [47/133] Xamarin.AndroidX.Loader.dll -> Xamarin.AndroidX.Loader.dll.so
  [124/133] System.Threading.dll -> System.Threading.dll.so
  [125/133] System.Xml.Linq.dll -> System.Xml.Linq.dll.so
  [48/133] Xamarin.AndroidX.Navigation.Common.Android.dll -> Xamarin.AndroidX.Navigation.Common.Android.dll.so
  [126/133] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
  [49/133] Xamarin.AndroidX.Navigation.Fragment.dll -> Xamarin.AndroidX.Navigation.Fragment.dll.so
  [127/133] System.Xml.ReaderWriter.dll -> System.Xml.ReaderWriter.dll.so
  [128/133] netstandard.dll -> netstandard.dll.so
  [129/133] System.dll -> System.dll.so
  [50/133] Xamarin.AndroidX.Navigation.Runtime.Android.dll -> Xamarin.AndroidX.Navigation.Runtime.Android.dll.so
  [51/133] Xamarin.AndroidX.Navigation.UI.dll -> Xamarin.AndroidX.Navigation.UI.dll.so
  [130/133] Mono.Android.Runtime.dll -> Mono.Android.Runtime.dll.so
  [52/133] Xamarin.AndroidX.RecyclerView.dll -> Xamarin.AndroidX.RecyclerView.dll.so
  [131/133] Java.Interop.dll -> Java.Interop.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
  [132/133] Mono.Android.dll -> Mono.Android.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
  [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
  [133/133] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
  [74/133] System.Collections.dll -> System.Collections.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:08:09.80
Run "dotnet tool restore" to make the "xharness" command available.
  Tests completed with exit code: 1

🟢 With fix — 📱 WindowTests (ReplacedFlyoutPageRootClearsOldContainerView): FAIL ❌ · 1031s

(truncated to last 15,000 chars)

m.Text.Encoding.dll.so
  [118/133] System.Text.Encodings.Web.dll -> System.Text.Encodings.Web.dll.so
  [42/133] Xamarin.AndroidX.Fragment.dll -> Xamarin.AndroidX.Fragment.dll.so
  [43/133] Xamarin.AndroidX.Lifecycle.Common.Jvm.dll -> Xamarin.AndroidX.Lifecycle.Common.Jvm.dll.so
  [44/133] Xamarin.AndroidX.Lifecycle.LiveData.Core.dll -> Xamarin.AndroidX.Lifecycle.LiveData.Core.dll.so
  [45/133] Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll.so
  [46/133] Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll.so
  [119/133] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
  [120/133] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
  [47/133] Xamarin.AndroidX.Loader.dll -> Xamarin.AndroidX.Loader.dll.so
  [121/133] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
  [48/133] Xamarin.AndroidX.Navigation.Common.Android.dll -> Xamarin.AndroidX.Navigation.Common.Android.dll.so
  [122/133] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
  [123/133] System.Text.Json.dll -> System.Text.Json.dll.so
  [49/133] Xamarin.AndroidX.Navigation.Fragment.dll -> Xamarin.AndroidX.Navigation.Fragment.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
  [50/133] Xamarin.AndroidX.Navigation.Runtime.Android.dll -> Xamarin.AndroidX.Navigation.Runtime.Android.dll.so
  [127/133] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
  [128/133] System.dll -> System.dll.so
  [51/133] Xamarin.AndroidX.Navigation.UI.dll -> Xamarin.AndroidX.Navigation.UI.dll.so
  [129/133] netstandard.dll -> netstandard.dll.so
  [130/133] Mono.Android.Runtime.dll -> Mono.Android.Runtime.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
  [131/133] Java.Interop.dll -> Java.Interop.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
  [133/133] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
  [74/133] System.Collections.dll -> System.Collections.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:08:20.10
[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=Window
�[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:4
�[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

⚠️ Failure Details

  • WindowTests (ReplacedFlyoutPageRootClearsOldContainerView) FAILED with fix (should pass)
📁 Fix files reverted (153 files)
  • .config/dotnet-tools.json
  • eng/Signing.props
  • eng/Version.Details.xml
  • eng/Versions.props
  • eng/pipelines/ci-copilot.yml
  • src/Compatibility/Core/src/Android/Renderers/SwipeViewRenderer.cs
  • src/Compatibility/Core/src/MacOS/Extensions/NSMenuExtensions.cs
  • src/Compatibility/Core/src/iOS/EventTracker.cs
  • src/Compatibility/Core/src/iOS/Renderers/SwipeViewRenderer.cs
  • src/Controls/samples/Controls.Sample/Pages/Controls/MapsGalleries/MapPinsGallery.xaml
  • src/Controls/samples/Controls.Sample/Pages/Controls/MapsGalleries/MapPinsGallery.xaml.cs
  • src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs
  • src/Controls/src/Core/ActionSheetArguments.cs
  • src/Controls/src/Core/AlertArguments.cs
  • src/Controls/src/Core/BindableObject.cs
  • src/Controls/src/Core/BindableProperty.cs
  • src/Controls/src/Core/Button/Button.iOS.cs
  • src/Controls/src/Core/Compatibility/Handlers/FlyoutPage/iOS/PhoneFlyoutPageRenderer.cs
  • src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/Android/SearchHandlerAppearanceTracker.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFragmentContainer.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellItemRenderer.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutLayoutManager.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRootRenderer.cs
  • src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellTableViewController.cs
  • src/Controls/src/Core/Editor/Editor.Mapper.cs
  • src/Controls/src/Core/Editor/Editor.iOS.cs
  • src/Controls/src/Core/Entry/Entry.Mapper.cs
  • src/Controls/src/Core/Entry/Entry.iOS.cs
  • src/Controls/src/Core/Handlers/Items/Android/GridLayoutSpanSizeLookup.cs
  • src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
  • src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Windows.cs
  • src/Controls/src/Core/Handlers/Items/iOS/ItemsViewController.cs
  • src/Controls/src/Core/Handlers/Items/iOS/ItemsViewDelegator.cs
  • src/Controls/src/Core/Handlers/Items2/iOS/CarouselViewController2.cs
  • src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs
  • src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewController2.cs
  • src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewDelegator2.cs
  • src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs
  • src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs
  • src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs
  • src/Controls/src/Core/Label/Label.Mapper.cs
  • src/Controls/src/Core/Label/Label.iOS.cs
  • src/Controls/src/Core/ListView/ListView.cs
  • src/Controls/src/Core/NavigationPage/NavigationPage.cs
  • src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs
  • src/Controls/src/Core/Platform/AlertManager/AlertManager.cs
  • src/Controls/src/Core/Platform/Android/BottomNavigationViewUtils.cs
  • src/Controls/src/Core/Platform/Android/DragAndDropGestureHandler.cs
  • src/Controls/src/Core/Platform/Android/TabbedPageManager.cs
  • src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.iOS.cs
  • src/Controls/src/Core/Platform/iOS/Extensions/FormattedStringExtensions.cs
  • src/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cs
  • src/Controls/src/Core/PromptArguments.cs
  • src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/RadioButton/RadioButton.cs
  • src/Controls/src/Core/RadioButton/RadioButtonGroup.cs
  • src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs
  • src/Controls/src/Core/Setter.cs
  • src/Controls/src/Core/Shadow.cs
  • src/Controls/src/Core/Shapes/Shape.cs
  • src/Controls/src/Core/Shell/Shell.cs
  • src/Controls/src/Core/Shell/ShellNavigationManager.cs
  • src/Controls/src/Core/TabbedPage/TabbedPage.Windows.cs
  • src/Controls/src/Core/VisualElement/VisualElement.cs
  • src/Controls/src/Core/VisualStateManager.cs
  • src/Controls/src/Xaml/ApplyPropertiesVisitor.cs
  • src/Controls/src/Xaml/MarkupExtensions/OnIdiomExtension.cs
  • src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs
  • src/Core/maps/src/Handlers/Map/MapHandler.Android.cs
  • src/Core/maps/src/Handlers/MapPin/MapPinHandler.Android.cs
  • src/Core/maps/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
  • src/Core/src/Graphics/MauiDrawable.Android.cs
  • src/Core/src/Handlers/Button/ButtonHandler.Android.cs
  • src/Core/src/Handlers/Button/ButtonHandler.cs
  • src/Core/src/Handlers/Button/ButtonHandler.iOS.cs
  • src/Core/src/Handlers/DatePicker/DatePickerHandler.MacCatalyst.cs
  • src/Core/src/Handlers/Editor/EditorHandler.iOS.cs
  • src/Core/src/Handlers/Entry/EntryHandler.cs
  • src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
  • src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Standard.cs
  • src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Tizen.cs
  • src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs
  • src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cs
  • src/Core/src/Handlers/Label/LabelHandler.cs
  • src/Core/src/Handlers/Label/LabelHandler.iOS.cs
  • src/Core/src/Handlers/RadioButton/RadioButtonHandler.cs
  • src/Core/src/Handlers/RadioButton/RadioButtonHandler.iOS.cs
  • src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs
  • src/Core/src/Handlers/ScrollView/ScrollViewHandler.Windows.cs
  • src/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cs
  • src/Core/src/Handlers/ShapeView/ShapeViewHandler.Standard.cs
  • src/Core/src/Handlers/ShapeView/ShapeViewHandler.cs
  • src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs
  • src/Core/src/Handlers/TimePicker/TimePickerHandler.Android.cs
  • src/Core/src/Handlers/TimePicker/TimePickerHandler.Windows.cs
  • src/Core/src/Handlers/TimePicker/TimePickerHandler.cs
  • src/Core/src/Handlers/TimePicker/TimePickerHandler.iOS.cs
  • src/Core/src/Hosting/EssentialsMauiAppBuilderExtensions.cs
  • src/Core/src/Platform/Android/BorderDrawable.cs
  • src/Core/src/Platform/Android/ContainerView.cs
  • src/Core/src/Platform/Android/MauiSwipeView.cs
  • src/Core/src/Platform/Android/MauiWebView.cs
  • src/Core/src/Platform/Android/Navigation/NavigationRootManager.cs
  • src/Core/src/Platform/Android/RadioButtonExtensions.cs
  • src/Core/src/Platform/Android/TimePickerExtensions.cs
  • src/Core/src/Platform/Windows/ContentPanel.cs
  • src/Core/src/Platform/Windows/MauiPasswordTextBox.cs
  • src/Core/src/Platform/Windows/MauiToolbar.xaml.cs
  • src/Core/src/Platform/Windows/RadioButtonExtensions.cs
  • src/Core/src/Platform/Windows/RootNavigationView.cs
  • src/Core/src/Platform/Windows/ScrollViewerExtensions.cs
  • src/Core/src/Platform/Windows/TimePickerExtensions.cs
  • src/Core/src/Platform/iOS/ButtonExtensions.cs
  • src/Core/src/Platform/iOS/LayerExtensions.cs
  • src/Core/src/Platform/iOS/MauiPageControl.cs
  • src/Core/src/Platform/iOS/MauiSwipeView.cs
  • src/Core/src/Platform/iOS/MauiTextView.cs
  • src/Core/src/Platform/iOS/MauiView.cs
  • src/Core/src/Platform/iOS/TimePickerExtensions.cs
  • src/Core/src/Platform/iOS/WrapperView.cs
  • src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
  • src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
  • src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
  • src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
  • src/Core/src/ViewExtensions.cs
  • src/Core/src/WindowExtensions.cs
  • src/Essentials/src/AssemblyInfo/AssemblyInfo.shared.cs
  • src/Essentials/src/Clipboard/Clipboard.shared.cs
  • src/Essentials/src/FilePicker/FilePicker.tizen.cs
  • src/Essentials/src/FileSystem/FileSystemUtils.android.cs
  • src/Essentials/src/FileSystem/FileSystemUtils.shared.cs
  • src/Essentials/src/MainThread/MainThread.netstandard.cs
  • src/Essentials/src/MainThread/MainThread.shared.cs
  • src/Essentials/src/MediaPicker/MediaPicker.ios.cs
  • src/Essentials/src/MediaPicker/MediaPicker.tizen.cs
  • src/Graphics/src/Graphics/Platforms/Android/PlatformGraphicsView.cs
  • src/Graphics/src/Graphics/Platforms/MaciOS/PlatformCanvas.cs
  • src/Graphics/src/Graphics/Platforms/Windows/PlatformGraphicsView.cs
  • src/Graphics/src/Graphics/Platforms/iOS/PlatformGraphicsView.cs
  • src/SingleProject/Resizetizer/src/GenerateTizenManifest.cs
  • src/SingleProject/Resizetizer/src/SkiaSharpSvgTools.cs
  • src/Templates/src/templates/maui-aspire-servicedefaults/MauiAspire.1.ServiceDefaults.csproj

New files (not reverted):

  • src/Controls/src/Core/Handlers/Items/iOS/IScrollTrackingDelegator.cs
  • src/Controls/src/Core/Platform/AlertManager/DelegateAlertSubscription.cs
  • src/Core/src/Handlers/HybridWebView/HybridWebViewHelper.cs
  • src/Core/src/ScreenshotDispatch.cs

🧪 UI Tests — ViewBaseTests

Detected UI test categories: ViewBaseTests

🧪 UI Test Execution Results

⏭️ SKIPPED — 0 passed, 0 failed, 1 skipped (platform: android)

Category Result Tests Duration Notes
ViewBaseTests ⏭️ SKIPPED 3s Runner threw an exception

Failures here are informational only — they do not block the gate or affect try-fix candidate scoring.

Deep UI tests — 118 passed, 0 failed across 1 category on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
controls-ViewBaseTests 118/119 ✓
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)

🔍 Pre-Flight — Context & Validation

Pre-Flight: PR #35372 — Fix Android stale ContainerView root leak

Issue: #35371 — Android: Stale ContainerView retains replaced FlyoutPage graph
Author: @AdamEssenmacher (community ✨)
Base branch: inflight/current
Target milestone: .NET 10.0 SR8
Labels: t/bug, platform/android, area-navigation, i/regression, regressed-in-10-preview1, s/verified, s/triaged
Platform under review: Android

Bug Summary

On Android, replacing Window.Page from a FlyoutPage root with another page leaves the entire old FlyoutPage graph (root FlyoutPage, flyout ContentPage, detail NavigationPage, detail ContentPage) reachable after forced GC. The reproducer shows Weak refs alive: 4/4. Identified as a regression in 10-preview1.

Root Cause

NavigationRootManager.ClearPlatformParts() (the method called by Connect when installing a new root, and by Disconnect) nulled out _rootView without first clearing the Android ContainerView's CurrentView property. The old ContainerView instance (still held by the Android view hierarchy / detach pipeline) retained _view = <old FlyoutPage> and _mainView = <old DrawerLayout>. That cross-managed-to-managed reference kept the entire previous virtual tree rooted.

ContainerView.SetView(null) cascades: clearing _view and then calling MainView = null, which RemoveViews the child and drops _mainView. Both must be cleared to fully sever the reference.

File Classification

File Type Risk
src/Core/src/Platform/Android/Navigation/NavigationRootManager.cs Production (Android platform) Low — 3-line guarded addition in private cleanup method
src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs Test (Android-only, #if ANDROID) None — adds a Window-category device test

Code Review Summary (independence-first)

Verdict Confidence
LGTM High

❌ Errors: None.

⚠️ Warnings: None of consequence. The pattern if (_rootView is ContainerView containerView) containerView.CurrentView = null; is idiomatic, null-safe, type-safe, and confined to a private method that is only invoked from Connect (line 53) and Disconnect (line 147) — both of which immediately follow up by reassigning or finalising the root, so there is no observable side effect on the live UI.

💡 Suggestions (non-blocking):

  • Could move the CurrentView clearing into ContainerView.Dispose/finaliser-side cleanup, but that broadens scope unnecessarily. The current targeted clearing is the lowest-risk fix.
  • Could symmetrically clear MainView explicitly; not needed because CurrentView setter cascades.

Failure-mode probes (relevant ones only):

  1. _rootView is null (first Connect) → guarded by is ContainerView pattern → safe (no-op).
  2. _rootView is a DrawerLayout (FlyoutPage root without outer ContainerView wrap, line 62-66) → guarded by is ContainerView → safe (no-op). NOTE: DrawerLayout and ContainerView are distinct types — see lines 63 vs 69; the is pattern correctly distinguishes them.
  3. _rootView is the inflated navigationlayout CoordinatorLayout (non-flyout root, line 87) → guarded → safe (no-op).
  4. _rootView IS a ContainerView wrapping a DrawerLayout (the FlyoutPage-on-API≥? path at line 67–71) → fix activates → CurrentView = nullSetView(null) → cascades to MainView = nullRemoveView of the old DrawerLayout child → entire managed graph severed. ✅
  5. ContainerView.SetView early-returns if view == _view; setting to null when already null is a safe no-op. ✅

Blast radius: Only affects the FlyoutPage-rooted Android window path (case 4 above). Non-flyout roots and Disconnect-on-first-call are no-ops. No public API change. No threading change (called on UI thread by the navigation handler).

Test Coverage

The PR adds WindowTests.ReplacedFlyoutPageRootClearsOldContainerView. The test:

  1. Creates a FlyoutPage root, installs as Window.Page.
  2. Captures the ContainerView and asserts it has a non-null CurrentView/MainView.
  3. Replaces Window.Page with a plain ContentPage.
  4. Asserts the OLD ContainerView.CurrentView is null, MainView is null, and the new RootView is a different instance.

This is a direct unit-of-behaviour test for the symptom, narrower than the original GC-based reproducer but appropriate for device-test infrastructure.

Gate Result Recap

Gate was reported ❌ FAILED:

  • Without fix: test FAILED (✅ as expected).
  • With fix: test FAILED — but failure mode is XHarness exit code: 78 (PACKAGE_INSTALLATION_FAILURE)cmd: Can't find service: package. This is the Android package system service crashing on the emulator during apk install; it is infrastructure flake, not a test logic failure. The fix run never produced a test result.

The PR description corroborates: author ran the new test + 16/16 Window suite + 61/61 Memory suite locally and reports all passing, plus the standalone repro app reaches Weak refs alive: 0/4.

Recommendation Going Into Phase 2

  • The PR fix is minimal, correct, and well-targeted.
  • Try-Fix should explore independent alternatives (clear MainView instead, clear inside ContainerView dispose path, clear in Disconnect only, clear via IDisposable pattern on ContainerView).
  • The infra-flake gate result should NOT downgrade the PR.

🔬 Code Review — Deep Analysis

Code Review: PR #35372 (Independent assessment)

Approach

Read the diff and the surrounding code (NavigationRootManager.cs, ContainerView.cs) BEFORE re-reading the PR description, to avoid anchoring bias.

Diff Under Review

@@ src/Core/src/Platform/Android/Navigation/NavigationRootManager.cs @@ ClearPlatformParts()
 void ClearPlatformParts()
 {
     _pendingFragment?.Dispose();
     _pendingFragment = null;
+    if (_rootView is ContainerView containerView)
+        containerView.CurrentView = null;
+
     DrawerLayout = null;
     _rootView = null;
     _toolbarElement = null;
     _managedCoordinatorLayout = null;
 }

Plus an Android device test ReplacedFlyoutPageRootClearsOldContainerView in WindowTests.cs.

Findings

❌ Errors

(none)

⚠️ Warnings

(none of consequence)

💡 Suggestions (non-blocking)

  1. Brace style. The repo convention is to omit braces on single-statement if only sparingly; nearby code in this file uses braces. Adding {} would be marginally more consistent, but the current form matches several other one-line if statements in the same file (e.g. if (containerView is DrawerLayout dl) patterns nearby use braces, but the ContainerView-cast pattern matches if (_rootView is null) at line 96). Not a blocker.
  2. Test naming / Display name. [Fact(DisplayName = "Replaced FlyoutPage Root Clears Old ContainerView")] — descriptive and consistent with surrounding tests.
  3. The local helper CreateFlyoutRoot() is added inside #if ANDROID and is only used by the new test — appropriately scoped.

Failure-mode probes

Scenario Behavior with fix Verdict
_rootView == null (very first Connect) is ContainerView is false → skipped ✅ Safe
_rootView is DrawerLayout (line 62-66, FlyoutPage where ToContainerView returns the DrawerLayout directly) is ContainerView is false → skipped. DrawerLayout's own cleanup path still applies. ✅ Safe — but worth noting: this path does NOT receive the leak fix. If FlyoutPage ever lands directly as DrawerLayout and that DrawerLayout retains the virtual view, the leak persists. Search of ToContainerView for FlyoutPage shows it returns ContainerView wrapping a DrawerLayout (line 67-71 path), so this should be the dominant path.
_rootView is CoordinatorLayout (non-flyout, line 87) is ContainerView is false → skipped ✅ Safe
_rootView is ContainerView (FlyoutPage real path) CurrentView = nullSetView(null) → cascades clear of _view AND MainView → child view removed ✅ Fixes the leak
Re-entry: ClearPlatformParts called twice in a row Second call: _rootView is already null → skipped ✅ Safe
ContainerView disposed already CurrentView setter just assigns refs; no JNI calls; safe even after Activity teardown ✅ Safe

Blast radius

  • Method is private and only invoked from Connect (line 53) and Disconnect (line 147).
  • Connect immediately re-establishes a new _rootView, so any UI-visible effect of clearing CurrentView on the old, about-to-be-discarded view is none.
  • Disconnect is followed by SetContentView(null), also no UI consequence.
  • No public API surface changed.
  • No threading change.
  • No NativeAOT / trimming concern (no reflection).
  • No allocation in steady state (one type test + one assignment).

Verdict

LGTM (confidence: high)

The change is the minimum necessary edit to break the managed-reference cycle keeping the previous FlyoutPage graph alive. The added device test directly asserts the post-condition. The PR description's local validation (16/16 Window, 61/61 Memory, repro app Weak refs alive: 0/4) is consistent with the analysis.

The gate "with fix" failure was an Android emulator infrastructure flake (XHarness exit code 78 / cmd: Can't find service: package), not a test-logic failure. The PR's correctness is not in doubt.


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix-1 (Handler Lifecycle dim.) Extract ContainerView.Disconnect() helper; call from ClearPlatformParts ⚪ Not executed (Android infra) 2 files Functionally identical to PR; adds ceremony for no clear win
2 try-fix-2 (Android Platform dim.) Override OnDetachedFromWindow in ContainerView to null CurrentView ⚪ Not executed 1 file Higher blast radius — detach fires in transient scenarios
3 try-fix-3 (Memory / IDisposable dim.) Override Dispose(bool) and call Dispose from ClearPlatformParts ⚪ Not executed 2 files Triggers JNI handle release on a view AndroidX may still touch — risky
4 try-fix-4 (Navigation flow dim.) Clear CurrentView at top of Connect (before ClearPlatformParts) ⚪ Not executed 1 file Misses Disconnect path; functional subset of PR
PR PR #35372 Clear CurrentView inside ClearPlatformParts when _rootView is ContainerView ✅ Author's local: 16/16 Window, 61/61 Memory; repro 0/4 weak refs. Gate "with fix" run was infra-flake (XHarness 78 / package service crash) 2 files (1 prod + 1 test) Smallest, most targeted, covers both Connect and Disconnect call sites

Cross-Pollination

Model (analytical) Round New Ideas? Details
Handler-lifecycle dim. 2 No "PR fix subsumes my approach with less code."
Android-platform dim. 2 No "OnDetachedFromWindow is too aggressive — withdraw."
Memory/IDisposable dim. 2 No "Dispose semantics are risky on Android views — withdraw."
Navigation-flow dim. 2 No "PR's location inside ClearPlatformParts is strictly better coverage."

Exhausted: Yes
Selected Fix: PR #35372 (as submitted) — Smallest diff, correct abstraction (placed at the convergence point of both Connect and Disconnect), null/type-safe via pattern matching, no risk of broadening blast radius.

Why None of the Try-Fix Alternatives Were Run on Device

The pre-run gate already demonstrated that the Android emulator in this CI environment cannot install APKs (XHarness exit code 78 (PACKAGE_INSTALLATION_FAILURE) / cmd: Can't find service: package). All four alternatives would hit the same blocker. They are evaluated analytically here against the PR fix on these axes: correctness, coverage, blast radius, code-quality, and codebase consistency. Per skill policy, candidates with no test result are ranked below candidates that have a verified pass; the PR fix has the author's local empirical evidence (full Window + Memory category passing, plus the original GC-based reproducer landing at 0/4) as its proof point.

Author's Local Validation (from PR description)

  • New test fails before fix (old FlyoutPage still in CurrentView).
  • Android Window device tests passed: 16/16.
  • Android Memory category passed: 61/61.
  • Standalone repro app validated: all tracked page counts reached 0 and Weak refs alive: 0/4.

📋 Report — Final Recommendation

PR #35372 — Multi-Candidate Review Report

Recommendation

✅ APPROVE the PR as submitted (pr). No code changes are required.

Comparative Analysis

The review considered six candidates against inflight/current:

Candidate Diff scope Test outcome Coverage of leak Blast radius Verdict
pr +3 prod lines, +50 test lines Gate "without fix" FAIL ✅; gate "with fix" infra-flaked (XHarness 78); author local: 16/16 Window + 61/61 Memory + repro 0/4 Connect + Disconnect (both go through ClearPlatformParts) Minimal (private method, type-pattern guarded) ✅ WINNER
pr-plus-reviewer pr + 4 explanatory comment lines Identical to pr ✅ Same Same ⚪ Neutral; no behavior delta
try-fix-1 Extract ContainerView.Disconnect() Not run (infra) ✅ Same Same + tiny API broadening ❌ More code, no benefit
try-fix-2 Override OnDetachedFromWindow Not run (infra) Broader, but unsafe — detach is too frequent (fragment transactions, config changes, recycling) High ❌ Risk
try-fix-3 Dispose(bool) override + Dispose-from-host Not run (infra) ✅ Same High — JNI handle release on a view AndroidX may re-touch ❌ Risk
try-fix-4 Clear CurrentView only at top of Connect Not run (infra) ❌ Misses Disconnect Same as PR ❌ Functional subset of PR

Why pr wins (and ranks above try-fix-* despite their "not run" status)

Per the task rule "candidates that failed regression tests MUST be ranked lower than candidates that passed them": the PR is the only candidate with empirical evidence of passing the regression assertion (the author's local 16/16 Window + 61/61 Memory + repro app). The try-fix alternatives have neither passing nor failing test results in this environment — but they are also functionally subset of, or strictly riskier than, the PR. So even on pure analytical grounds the PR wins.

Gate Failure Interpretation

The pre-run gate reported ❌ FAILED, but the failure of the "with fix" arm is:

XHarness exit code: 78 (PACKAGE_INSTALLATION_FAILURE)
cmd: Failure calling service package: Broken pipe (32)
adb: failed to install ...: cmd: Can't find service: package

This is the Android package system service crashing on the emulator mid-install. The fix code itself never ran on-device. The "without fix" arm successfully reproduced the bug (test FAIL as expected), confirming the new test correctly characterises the leak. Combined with the author's local validation, the PR's correctness is well-supported.

Code-Review Findings

No ❌ Errors. No ⚠️ Warnings of consequence. One non-blocking 💡 suggestion: add an explanatory comment on the new lines (captured as the pr-plus-reviewer candidate). Optional polish; not required for merge.

Sign-off Checklist

  • Root cause identified and matches the issue description.
  • Fix is minimal, type-safe (pattern matching), and null-safe.
  • Placed at the right abstraction layer (ClearPlatformParts is the convergence point).
  • No public API change.
  • Targeted device test added (ReplacedFlyoutPageRootClearsOldContainerView).
  • Author provided strong local empirical evidence (memory category 61/61, repro app 0/4 weak refs).
  • No regression risk to non-FlyoutPage roots (guarded by is ContainerView).
  • Targets .NET 10.0 SR8 against inflight/current — correct branch.

Final Verdict

Recommend merge of PR #35372 as-is. The fix is the minimum correct change; alternative approaches either duplicate it more verbosely, miss a code path, or introduce significantly higher risk.


@MauiBot MauiBot added s/agent-review-incomplete s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels May 11, 2026
@kubaflo
kubaflo merged commit c7c0f57 into dotnet:inflight/current May 11, 2026
30 of 35 checks passed
@AdamEssenmacher
AdamEssenmacher deleted the issue-35371 branch May 11, 2026 18:47
@github-actions github-actions Bot added this to the .NET 10 SR7 milestone May 11, 2026
@kubaflo kubaflo added s/agent-gate-failed AI could not verify tests catch the bug s/agent-changes-requested AI agent recommends changes - found a better alternative or issues and removed s/agent-review-incomplete labels May 20, 2026
PureWeen pushed a commit that referenced this pull request Jun 2, 2026
### Description of Change

Fixes an Android leak when replacing `Window.Page` from a `FlyoutPage`
root with another page while the window remains active.

The old Flyout root is hosted through an Android `ContainerView`. During
root replacement, `NavigationRootManager.ClearPlatformParts()` dropped
`_rootView` without clearing the old `ContainerView.CurrentView`,
leaving the replaced FlyoutPage graph reachable through the stale
container. The fix clears `CurrentView` before dropping the old root
view, which also clears `MainView`.

Added Android device coverage proving that replacing an active
FlyoutPage root clears the old root `ContainerView.CurrentView` and
`MainView`.

Validation:
- Verified the new test fails before the fix with the old `FlyoutPage`
still in `CurrentView`.
- Android Window device tests passed: 16/16.
- Android Memory category passed: 61/61.
- Standalone repro app validated: all tracked page counts reached 0 and
`Weak refs alive: 0/4`.

### Issues Fixed

Fixes #35371

---------
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
### Description of Change

Fixes an Android leak when replacing `Window.Page` from a `FlyoutPage`
root with another page while the window remains active.

The old Flyout root is hosted through an Android `ContainerView`. During
root replacement, `NavigationRootManager.ClearPlatformParts()` dropped
`_rootView` without clearing the old `ContainerView.CurrentView`,
leaving the replaced FlyoutPage graph reachable through the stale
container. The fix clears `CurrentView` before dropping the old root
view, which also clears `MainView`.

Added Android device coverage proving that replacing an active
FlyoutPage root clears the old root `ContainerView.CurrentView` and
`MainView`.

Validation:
- Verified the new test fails before the fix with the old `FlyoutPage`
still in `CurrentView`.
- Android Window device tests passed: 16/16.
- Android Memory category passed: 61/61.
- Standalone repro app validated: all tracked page counts reached 0 and
`Weak refs alive: 0/4`.

### Issues Fixed

Fixes #35371

---------
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 20, 2026
@sheiksyedm

Copy link
Copy Markdown
Contributor

This PR reverted via #36152

@github-actions github-actions Bot modified the milestones: .NET 10 SR7, .NET 10 SR9 Jul 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

community ✨ Community Contribution s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-failed AI could not verify tests catch the bug s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android: Stale ContainerView retains replaced FlyoutPage graph

6 participants