Skip to content

[Android] Fix RenderThread SIGSEGV crash with multiple auto-sizing WebViews in ScrollView#35822

Merged
kubaflo merged 1 commit into
dotnet:inflight/currentfrom
praveenkumarkarunanithi:fix-35771
Jun 11, 2026
Merged

[Android] Fix RenderThread SIGSEGV crash with multiple auto-sizing WebViews in ScrollView#35822
kubaflo merged 1 commit into
dotnet:inflight/currentfrom
praveenkumarkarunanithi:fix-35771

Conversation

@praveenkumarkarunanithi

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue.
Thank you!

Root Cause

When multiple WebViews are placed inside a ScrollView or other auto-sizing layouts with unconstrained dimensions, Android initially assigns each WebView a partial size during the first layout pass — either width > 0 && height == 0 (vertical layouts) or width == 0 && height > 0 (horizontal layouts) — before content measurement completes.

At this transient state, the flash-prevention logic introduced in PR #33207 sets ClipBounds = (0,0,0,0) on the native view. Android’s RenderThread detects the non-null ClipBounds, invokes the GL functor, and receives a zero-area Skia canvas. SkSurface::getCanvas() then returns null, causing a native SIGSEGV crash (0x20) inside RenderThread.

Because this is a native rendering crash, nothing appears in managed logs.

The same crash also occurs during PopAsync if the page is dismissed before layout completes. The earlier Task.Delay(400) workaround only bypassed the crash window incidentally.


Description of Change

Added a per-instance _isAutoSizing latch in both MauiWebView and MauiHybridWebView inside UpdateClipBounds.

The updated logic detects both confirmed dangerous transient layout states:

  • width > 0 && height == 0 — vertically auto-sizing WebView
  • width == 0 && height > 0 — horizontally auto-sizing WebView

Once either state is detected, _isAutoSizing is permanently latched to true to survive layout oscillation where a zero dimension can temporarily reappear after valid measurement.

While latched, ClipBounds is explicitly set to null, preventing Android’s RenderThread from scheduling the GL functor entirely. Any non-null ClipBounds value — including (0,0,0,0) — still triggers the GL pipeline and reproduces the crash.

Normal fixed-size WebViews that never enter these transient states remain unaffected and continue using exact ClipBounds for flash prevention.


Regression Introduced By

PR #33207

Issues Fixed

Fixes #35771

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Note: This is an Android-only crash — the SIGSEGV occurs in Android's native RenderThread (GLFunctorDrawable). The ClipBounds API and GL functor pipeline are Android-specific; iOS, Mac, and Windows use entirely different rendering stacks and are not affected.

Screenshots

Before Issue Fix After Issue Fix
BeforeFix.39.mov
AfterFix.46.mov

@github-actions

github-actions Bot commented Jun 9, 2026

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 -- 35822

Or

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

@vishnumenon2684 vishnumenon2684 added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Jun 9, 2026
@vishnumenon2684 vishnumenon2684 marked this pull request as ready for review June 9, 2026 14:41
@vishnumenon2684 vishnumenon2684 changed the title [WIP] [Android] Fix RenderThread SIGSEGV crash with multiple auto-sizing WebViews in ScrollView [Android] Fix RenderThread SIGSEGV crash with multiple auto-sizing WebViews in ScrollView Jun 9, 2026
@kubaflo

kubaflo commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/regression-check -p android

@kubaflo

kubaflo commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/regression-check -p android

@github-actions github-actions Bot added s/agent-review-in-progress AI review is currently running for this PR and removed s/agent-review-in-progress AI review is currently running for this PR labels Jun 10, 2026
@kubaflo

kubaflo commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/regression-check -p android

@github-actions github-actions Bot added s/agent-review-in-progress AI review is currently running for this PR and removed s/agent-review-in-progress AI review is currently running for this PR labels Jun 10, 2026
@dotnet dotnet deleted a comment from github-actions Bot Jun 10, 2026
@kubaflo

kubaflo commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

/review rerun

@vishnumenon2684

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

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

@kubaflo

kubaflo commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer -p android

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jun 11, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 2 findings

See inline comments for details.

// RenderThread to crash (SIGSEGV). Null disables clipping; the latch prevents later
// layout passes from re-enabling it before both dimensions are stable.
// https://github.com/dotnet/maui/issues/35771
if (_isAutoSizing || (width > 0 && height == 0) || (width == 0 && height > 0))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[major] Logic and Correctness — Once a WebView sees one partial-size pass, _isAutoSizing stays true forever, so later stable (width > 0 && height > 0) and fully collapsed (0,0) states keep ClipBounds = null instead of restoring the exact/zero clip rect. Concrete regression: an auto-sizing WebView that later reaches a normal non-WrapperView size permanently loses the flash-prevention clipping added for #31475/#33207/#35057; if it later collapses to (0,0), it also skips the existing zero-clip behavior. This only needs transient suppression for the partial-size state.

// RenderThread to crash (SIGSEGV). Null disables clipping; the latch prevents later
// layout passes from re-enabling it before both dimensions are stable.
// https://github.com/dotnet/maui/issues/35771
if (_isAutoSizing || (width > 0 && height == 0) || (width == 0 && height > 0))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[major] Logic and Correctness — Once a HybridWebView sees one partial-size pass, _isAutoSizing stays true forever, so later stable (width > 0 && height > 0) and fully collapsed (0,0) states keep ClipBounds = null instead of restoring the exact/zero clip rect. Concrete regression: an auto-sizing HybridWebView that later reaches a normal non-WrapperView size permanently loses the flash-prevention clipping added for #31475/#33207/#35057; if it later collapses to (0,0), it also skips the existing zero-clip behavior. This only needs transient suppression for the partial-size state.

@MauiBot MauiBot added s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jun 11, 2026
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
Hoists regression-fix PRs that are in flight (open against main or as
backports targeting the SR) into a prominent section right under the
Blocking summary — these were previously buried in Tier 2 of the
detailed regression breakdown.

Captures two classifications:
  - open-on-main:        fix PR is OPEN against main awaiting merge
                         (next action: watch for merge → open backport)
  - backport-in-progress: fix PR already merged, open backport targets SR
                         (next action: land the backport before ship)

The section is omitted entirely when no regression has an open fix PR
in flight, so green SR reports stay terse.

Example: SR8 (#35876) now surfaces #35822 (Android RenderThread crash
fix) and #35803 (TabbedPage navigation regression fix) at the top of
the issue instead of buried at line 100+ in the tier-2 detail.

10 new unit tests cover header rendering, link extraction, base-ref
display, status emoji, title truncation, ordering relative to Blocking
and Ship-readiness sections, and the empty-case omission.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@kubaflo kubaflo 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.

Could you please check the ai's suggestions?

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@praveenkumarkarunanithi — new AI review results are available based on this last commit: fc18b71.
fix and test update To request a fresh review after new comments or commits, comment /review rerun.

Gate Passed Code Review In Review Confidence Medium Platform Android

Review Sessions — click to expand
Gate — Test Before & After Fix

Gate Result: ✅ PASSED

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

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue35771 Issue35771 ✅ FAIL — 1113s ✅ PASS — 795s
🔴 Without fix — 🖥️ Issue35771: FAIL ✅ · 1113s

(truncated to last 15,000 chars)

ed.Tests/UITest.cs:line 576
 >>>>> 06/11/2026 14:10:29 The FixtureSetup threw an exception. Attempt 1/1.
 Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
    at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
    at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
    at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
    at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
 >>>>> 06/11/2026 14:10:29 Reset after force-close failed: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page

>>>>> 06/11/2026 14:10:29 PopAsyncFromAutoSizingWebViewPageShouldNotCrash Start
>>>>> 06/11/2026 14:10:44 PopAsyncFromAutoSizingWebViewPageShouldNotCrash Stop
>>>>> 06/11/2026 14:10:45 Log types: logcat, bugreport, server
>>>>> 06/11/2026 14:10:45 FixtureSetup for PopAsyncFromAutoSizingWebViewPageShouldNotCrash
>>>>> 06/11/2026 14:11:02 The FixtureSetup threw an exception. Attempt 0/1.
Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
   at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
>>>>> 06/11/2026 14:11:04 FixtureSetup for PopAsyncFromAutoSizingWebViewPageShouldNotCrash
>>>>> 06/11/2026 14:11:20 The FixtureSetup threw an exception. Attempt 1/1.
Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
   at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
>>>>> 06/11/2026 14:11:20 App became unresponsive, force-closing: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
>>>>> 06/11/2026 14:11:21 FixtureSetup for PopAsyncFromAutoSizingWebViewPageShouldNotCrash
>>>>> 06/11/2026 14:11:37 The FixtureSetup threw an exception. Attempt 0/1.
Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
   at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
>>>>> 06/11/2026 14:11:40 FixtureSetup for PopAsyncFromAutoSizingWebViewPageShouldNotCrash
>>>>> 06/11/2026 14:11:56 The FixtureSetup threw an exception. Attempt 1/1.
Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
   at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
>>>>> 06/11/2026 14:11:56 Reset after force-close failed: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
>>>>> 06/11/2026 14:11:56 Log types: logcat, bugreport, server
  Failed PopAsyncFromAutoSizingWebViewPageShouldNotCrash [1 m 26 s]
  Error Message:
   The app became unresponsive and was force-terminated: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
TearDown : The app became unresponsive and was force-terminated: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
  Stack Trace:
     at UITest.Appium.NUnit.UITestBase.UITestBaseTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 154
   at UITest.Appium.NUnit.UITestBase.TestTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 45
   at InvokeStub_UITestBase.TestTearDown(Object, Object, IntPtr*)

--TearDown
   at UITest.Appium.NUnit.UITestBase.UITestBaseTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 185
   at UITest.Appium.NUnit.UITestBase.TestTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 45
   at InvokeStub_UITestBase.TestTearDown(Object, Object, IntPtr*)

1)    at UITest.Appium.NUnit.UITestBase.UITestBaseTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 154
   at UITest.Appium.NUnit.UITestBase.TestTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 45
   at InvokeStub_UITestBase.TestTearDown(Object, Object, IntPtr*)


  Standard Error Messages:
 >>>>> 06/11/2026 14:11:02 The FixtureSetup threw an exception. Attempt 0/1.
 Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
    at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
    at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
    at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
    at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
 >>>>> 06/11/2026 14:11:20 The FixtureSetup threw an exception. Attempt 1/1.
 Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
    at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
    at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
    at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
    at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
 >>>>> 06/11/2026 14:11:20 App became unresponsive, force-closing: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
 >>>>> 06/11/2026 14:11:37 The FixtureSetup threw an exception. Attempt 0/1.
 Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
    at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
    at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
    at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
    at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
 >>>>> 06/11/2026 14:11:56 The FixtureSetup threw an exception. Attempt 1/1.
 Exception details: System.TimeoutException: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page
    at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
    at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
    at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
    at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
    at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
 >>>>> 06/11/2026 14:11:56 Reset after force-close failed: Android SIGSEGV crash with multiple auto-sizing WebViews in ScrollView on navigated page

NUnit Adapter 4.5.0.0: Test execution complete
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35771.trx

Test Run Failed.
Total tests: 3
     Failed: 3
 Total time: 5.5289 Minutes
>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35771.trx

🟢 With fix — 🖥️ Issue35771: PASS ✅ · 795s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:10:43.55
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14347527
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.15]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.40]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 3 of 3 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 06/11/2026 14:24:55 FixtureSetup for Issue35771(Android)
>>>>> 06/11/2026 14:24:57 HorizontalAutoSizingWebViewsShouldNotCrash Start
>>>>> 06/11/2026 14:25:02 HorizontalAutoSizingWebViewsShouldNotCrash Stop
  Passed HorizontalAutoSizingWebViewsShouldNotCrash [6 s]
>>>>> 06/11/2026 14:25:03 MultipleAutoSizingWebViewsInScrollViewShouldNotCrash Start
>>>>> 06/11/2026 14:25:07 MultipleAutoSizingWebViewsInScrollViewShouldNotCrash Stop
  Passed MultipleAutoSizingWebViewsInScrollViewShouldNotCrash [4 s]
>>>>> 06/11/2026 14:25:07 PopAsyncFromAutoSizingWebViewPageShouldNotCrash Start
>>>>> 06/11/2026 14:25:11 PopAsyncFromAutoSizingWebViewPageShouldNotCrash Stop
  Passed PopAsyncFromAutoSizingWebViewPageShouldNotCrash [4 s]
NUnit Adapter 4.5.0.0: Test execution complete
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35771.trx

Test Run Successful.
Total tests: 3
     Passed: 3
 Total time: 33.3625 Seconds
>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35771.trx

📁 Fix files reverted (3 files)
  • eng/pipelines/ci-copilot.yml
  • src/Core/src/Platform/Android/MauiHybridWebView.cs
  • src/Core/src/Platform/Android/MauiWebView.cs

UI Tests — Navigation,ScrollView,ViewBaseTests,WebView

Detected UI test categories: Navigation,ScrollView,ViewBaseTests,WebView

Deep UI tests — 453 passed, 0 failed across 4 categories on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
Navigation 88/89 ✓
ScrollView 195/196 ✓
ViewBaseTests 118/119 ✓
WebView 52/52 ✓
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)

Pre-Flight — Context & Validation

Issue: #35771 - [Android] Native RenderThread crash (SIGSEGV, GLFunctorDrawable / SkSurface::getCanvas null) with multiple auto-sizing WebViews on a navigated page — 10.0.70
PR: #35822 - [Android] Fix RenderThread SIGSEGV crash with multiple auto-sizing WebViews in ScrollView
Platforms Affected: Android
Files Changed: 2 implementation, 2 test

Key Findings

  • Regression introduced in 10.0.70 after WebView flash-prevention clipping: multiple unconstrained/auto-sizing Android WebViews can hit a transient partial layout state (w>0,h=0 or w=0,h>0) and crash RenderThread when non-null zero-area ClipBounds triggers GL functor drawing.
  • PR fix changes both Android MauiWebView and MauiHybridWebView, adding a per-instance permanent auto-sizing latch that sets ClipBounds = null after any partial-dimension layout state.
  • Regression tests are Android UI tests under UITestCategories.WebView, with host app cases covering vertical auto-sizing, horizontal auto-sizing, and PopAsync dismissal.
  • Inline PR review comments were not accessible via authenticated gh; public API returned no inline comments. gh CLI is unauthenticated in this environment.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: medium
Errors: 0 | Warnings: 3 | Suggestions: 2

Key code review findings:

  • ⚠️ Permanent latch disables #31475/#33207 flash-prevention clipping for dynamically-sized WebViews once they encounter a partial-dimension layout state (MauiWebView.cs:55-65, MauiHybridWebView.cs:61-71).
  • ⚠️ After latching, fully-collapsed (0,0) views also keep ClipBounds = null instead of restoring the zero clip rect (MauiWebView.cs:55, MauiHybridWebView.cs:61).
  • ⚠️ Reported CI failures include macOS WebView/other unrelated lanes; Android-specific implementation makes them unlikely to be PR-caused, but unauthenticated gh prevented full CI verification.
  • 💡 Test repro uses static HTML rather than the original OnPageFinished-driven height update; likely sufficient but worth documenting.
  • 💡 _isAutoSizing name describes current state less accurately than a latched "has seen partial layout/skip clip bounds" state.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #35822 Add a permanent per-WebView partial-dimension latch in MauiWebView and MauiHybridWebView; once w>0,h=0 or w=0,h>0 occurs, keep ClipBounds = null forever. ✅ PASSED (Gate) src/Core/src/Platform/Android/MauiWebView.cs, src/Core/src/Platform/Android/MauiHybridWebView.cs, UI test files Original PR

Code Review — Deep Analysis

Code Review — PR #35822

Independent Assessment

What this changes: Adds a permanent one-way _isAutoSizing boolean latch to MauiWebView and MauiHybridWebView. When UpdateClipBounds detects that exactly one dimension is zero while the other is positive — the transient intermediate state that auto-sizing layouts produce — it sets _isAutoSizing = true, immediately sets ClipBounds = null, and returns early. All subsequent calls to UpdateClipBounds also return early with ClipBounds = null once latched, regardless of the final stable dimensions. Three UI tests are added covering vertical auto-sizing, horizontal auto-sizing, and PopAsync navigation scenarios (Android-only via #if ANDROID).

Inferred motivation: PR #33207 introduced flash prevention by setting ClipBounds = (0,0,0,0) at startup. A non-null ClipBounds — even a zero-area one — causes Android's RenderThread to invoke the GL functor. When the WebView is in the transient one-dimension-zero state, the Skia canvas has zero area, SkSurface::getCanvas() returns null, and the RenderThread crashes with SIGSEGV. The fix prevents any non-null ClipBounds from being set during this dangerous window.

Is the approach sound? The latch design is correct in that: (a) null vs (0,0,0,0) is the right distinction — only non-null ClipBounds triggers the GL functor; (b) the latch is permanent because layout oscillation can cause the dangerous state to re-appear even after stable dimensions are observed; (c) MauiWebView/MauiHybridWebView are freshly constructed per handler connection (CreatePlatformView in both handlers), so the latch doesn't accumulate across different usages. The logic order _isAutoSizing || ... is optimal (short-circuit evaluation prevents redundant dimension checks after latching).

Reconciliation with PR Narrative

Author claims: SIGSEGV regression from PR #33207. Root cause: ClipBounds = (0,0,0,0) (non-null) set during the transient (w>0,h=0) or (w=0,h>0) layout state causes RenderThread to invoke the GL functor on a zero-area Skia canvas. Fix: _isAutoSizing latch → permanent ClipBounds = null. PopAsync crash also covered.

Agreement/disagreement: Root cause analysis is accurate. The (non-null ClipBounds) → (GL functor invoked) → (zero Skia canvas) → SIGSEGV chain is correctly identified and matches the code. The fix correctly uses null not Rect.Empty. The PR description correctly states this is an Android-only regression.

Findings

⚠️ Warning — Permanent latch silently disables flash prevention for dynamically-sized WebViews

File: MauiWebView.cs:55–65, MauiHybridWebView.cs:61–71

Once _isAutoSizing latches to true, every subsequent call to UpdateClipBounds returns early with ClipBounds = null — including calls where width > 0 && height > 0 (the stable final state). This permanently bypasses the flash-prevention logic from issue #31475. The most impactful scenario is the common pattern of setting HeightRequest inside OnPageFinished (the original issue's repro uses this): the WebView starts unconstrained (triggers the latch), then gets a stable size. After the latch, it has ClipBounds = null forever, meaning it can render at full-screen before its bounds are applied — the pre-#33207 "flash" behavior. This is a known acceptable tradeoff (crash beats visual flash), but it's not documented in the code or the PR description, and a team member later encountering unexpected flash regressions may not connect it to this latch.

⚠️ Warning — _isAutoSizing latch also intercepts the fully-collapsed (0,0) case after latching

File: MauiWebView.cs:55, MauiHybridWebView.cs:61

The latch guard (if (_isAutoSizing || ...)) short-circuits before reaching the else branch that sets ClipBounds = (0,0,0,0) for a fully-collapsed view. Once latched, if the view becomes fully hidden/collapsed (width == 0 && height == 0), ClipBounds remains null rather than being set to the zero clip rect. With ClipBounds = null, a zero-area Android view still lacks any rendering restriction, which could theoretically allow the WebView to paint outside its zero bounds. In practice, a size-0 view triggers no visible rendering and is unlikely to cause a crash since the RenderThread has nothing to schedule. However, this is a subtle behavioral difference from the original intent of the else branch.

⚠️ Warning — macOS UITests Controls WebView CI check is failing

This check (maui-pr-uitests (macOS UITests Controls WebView)) is in a failed state. macOS uses WKWebView and an entirely different rendering stack with no ClipBounds API, so this failure is almost certainly pre-existing and unrelated to this PR. Similarly, Android UITests Controls CollectionView and maui-pr-devicetests (Windows) are failing but clearly unrelated. The primary build (maui-pr) passes, and the Android ScrollView test suite passes, which is the most relevant check for this fix. Before merge, someone should confirm the macOS WebView failure is pre-existing and not a recently introduced regression.

💡 Suggestion — Test repro uses minimal HTML; the original issue used OnPageFinished-based dynamic sizing

File: TestCases.HostApp/Issues/Issue35771.cs:40–55

The host app repro pages use static HTML content (<html><body><p>WebView {i}</p></body></html>) without HeightRequest. This should still reproduce the crash state since unconstrained WebViews in a VerticalStackLayout produce the (w>0, h=0) layout intermediate. However, the issue's original repro sets HeightRequest = scrollHeight inside OnPageFinished, which is a more aggressive form of auto-sizing and was what originally triggered the crash. The existing tests are valid as written — a crash would cause the WaitForElement("Issue35771Ready") to time out — but documenting in a comment why the static HTML approach is sufficient would help future readers understand the repro.

💡 Suggestion — _isAutoSizing field name is slightly misleading after latching

File: MauiWebView.cs:20, MauiHybridWebView.cs:25

The field is named _isAutoSizing, but after latching it no longer means the view is currently auto-sizing — it means the view has experienced a partial-dimension layout pass and should therefore never have non-null ClipBounds. A name like _hasSeenPartialLayout or _skipClipBounds would be more accurate. This is minor since the comments above the field explain the semantics clearly.

Devil's Advocate

Is the permanent latch justified? The author's rationale is that layout oscillation can cause the dangerous state to reappear after a valid (w>0, h>0) observation. If the latch reset on (w>0, h>0) and a subsequent oscillation brought (w>0, h=0) back, the crash would recur. The permanent latch is the only safe option. ✓ Conclusion stands.

Could ClipBounds = null itself cause a crash? Looking at #31475 and #35013 (VerifyHybridWebViewWithShadow), ClipBounds = null is the correct value for WrapperView parents as well — the shadow/border test explicitly relies on null. The RenderThread crash specifically requires non-null ClipBounds with a zero-area view. Setting null removes the functor trigger entirely. ✓ Conclusion stands.

Is the #if ANDROID guard on tests too restrictive? The SIGSEGV is native to Android's GL functor pipeline (libhwui.so). iOS uses WKWebView rendering, Windows uses WebView2, macOS uses WKWebView. The ClipBounds API and GL functor path are Android-exclusive. The guard is correct. ✓ Conclusion stands.

Is the macOS WebView CI failure a red flag? No — the change touches only MauiWebView.cs and MauiHybridWebView.cs in Platform/Android/, which do not compile on macOS. The macOS WebView failure must be pre-existing. ✓ Conclusion stands.

Verdict: NEEDS_DISCUSSION

Confidence: medium
Summary: The core fix is technically correct and well-reasoned — the SIGSEGV root cause is accurately identified, the null vs. zero-rect distinction is the right lever, and the permanent latch prevents layout oscillation from reintroducing the crash. The primary concern warranting discussion is the permanent disabling of flash prevention for all WebViews that pass through an intermediate partial-layout state: this is a silent regression of the #31475/#33207 work for dynamically-sized WebViews (e.g., those that set HeightRequest in OnPageFinished). The tradeoff is probably correct (crash beats flash), but it needs explicit documentation and ideally a follow-up tracking issue. The CI failures on macOS and Windows are almost certainly pre-existing, but the macOS WebView failure should be confirmed pre-existing before merge.


Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix-1 Transient partial-size suppression: set ClipBounds = null only when exactly one dimension is positive and the other is zero; restore normal clipping for stable (w>0,h>0) and zero clip for (0,0). ✅ PASS 2 files Passed all 3 Issue35771 Android UI tests on emulator-5554; expert review found it meaningfully better than the PR latch because it preserves flash-prevention clipping after stable layout.
PR PR #35822 Permanent _isAutoSizing latch: after any partial-dimension state, keep ClipBounds = null forever. ✅ PASSED (Gate) 4 files Original PR fix. Gate already verified tests fail without fix and pass with fix.

Candidate 1 Details

Approach: Candidate 1 removes the permanent latch and treats the dangerous partial-dimension state as transient. It nulls ClipBounds only while width > 0 && height == 0 or width == 0 && height > 0, then returns to the existing WrapperView/exact-bounds clipping behavior when both dimensions are positive. It also preserves the original zero clip rect for (0,0).

Why it differs from the PR: The PR adds persistent state and permanently disables clipping after the first partial-size layout. Candidate 1 is stateless and local to the current size, so it fixes the crash without permanently regressing the flash-prevention behavior from #31475/#33207/#35057.

Test result: ✅ PASS. pwsh .github/scripts/BuildAndRunHostApp.ps1 -Platform android -TestFilter "Issue35771" built/deployed the Android host app, discovered 3 NUnit tests, and all 3 passed:

  • HorizontalAutoSizingWebViewsShouldNotCrash
  • MultipleAutoSizingWebViewsInScrollViewShouldNotCrash
  • PopAsyncFromAutoSizingWebViewPageShouldNotCrash

Expert review result: NEEDS_DISCUSSION, confidence high. The expert review recommended Candidate 1 over the PR's permanent latch, with the caveat that the PR description/code comments should document why the brief partial-dimension ClipBounds = null window is safe.

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 1 Yes Generated and tested transient partial-size suppression.
maui-expert-reviewer 1 No further candidate needed Reviewed Candidate 1 and recommended it over the PR latch; no blocking code findings, only documentation/discussion caveat.

Exhausted: No — stopped because Candidate 1 passed all requested Android regression tests and is demonstrably better than the PR fix.
Selected Fix: Candidate #1 — It preserves crash prevention while avoiding the PR's permanent flash-prevention regression and reducing per-instance state/complexity.


Report — Final Recommendation

Comparative Report — PR #35822

Candidates Compared

Candidate Approach Regression Tests Rank
pr-plus-reviewer PR fix with expert feedback applied: transiently suppress ClipBounds only during partial-dimension layout, then restore normal exact/zero clipping. ✅ PASS, same implementation strategy as try-fix-1 1
try-fix-1 Independent transient partial-size suppression; no persistent state. ✅ PASS 2
pr Permanent _isAutoSizing latch; after any partial-dimension pass, keep ClipBounds = null forever. ✅ PASS (Gate) 3

No STEP 5a candidates failed regression tests. If any had failed, they would be ranked below all passing candidates per the ranking rule.

Analysis

pr

The raw PR fix passes the gate and covers both Android MauiWebView and MauiHybridWebView, but the implementation is broader than necessary. The permanent latch fixes the crash by avoiding non-null zero-area ClipBounds during partial layout, but it also permanently disables clipping after layout stabilizes. That regresses the existing WebView flash-prevention behavior from #31475/#33207/#35057 for non-WrapperView WebViews and changes later (0,0) collapsed handling from a zero clip rect to no clip.

try-fix-1

try-fix-1 passed all three Android Issue35771 UI tests and directly targets the crash condition. It suppresses clipping only for the dangerous current size states (w > 0, h == 0 or w == 0, h > 0), then restores the pre-existing exact-bounds clipping for stable non-zero sizes and zero clipping for (0,0). This preserves the passing crash fix while avoiding the PR latch regression.

pr-plus-reviewer

The expert reviewer found the same actionable issue as the STEP 5a analysis: the PR should use transient partial-size suppression, not a permanent latch. Applying that feedback to the PR produces the same substantive implementation as try-fix-1, while keeping the PR's test coverage. Because this is the PR candidate after reviewer feedback and has the same passing behavior and safer clipping semantics as the best independent candidate, it is the strongest candidate.

Winner

Winner: pr-plus-reviewer

pr-plus-reviewer wins because it combines the PR's scope and regression coverage with the expert-reviewed transient suppression logic. It preserves the verified Android crash fix and avoids the raw PR's permanent loss of flash-prevention and zero-size clipping behavior.


Future Action — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jun 11, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current June 11, 2026 19:20
@kubaflo kubaflo merged commit 8fee09a into dotnet:inflight/current Jun 11, 2026
162 of 169 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR9 milestone Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-hybridwebview HybridWebView control area-controls-webview WebView partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

4 participants