Skip to content

Remove excessive measure call#31769

Open
PureWeen wants to merge 1 commit into
mainfrom
fix_wrapperview_measure_arrange
Open

Remove excessive measure call#31769
PureWeen wants to merge 1 commit into
mainfrom
fix_wrapperview_measure_arrange

Conversation

@PureWeen

Copy link
Copy Markdown
Member

Description of Change

The platformWrapperView.java base class already calls measure

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (getChildCount() == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
View child = getChildAt(0);
viewBounds.set(0, 0, MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
child.measure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight());
}

I'm not sure why we have an extra measure call inside layout.

If anything the tests will fail and I can add some comments to clarify why we are measuring again inside layout :-)

Copilot AI review requested due to automatic review settings September 24, 2025 23:52

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

This PR removes an extra measure call in the Android WrapperView's OnLayout method. The change eliminates redundant measurement since the base PlatformWrapperView.java class already handles measuring child views.

Key Changes

  • Removes duplicate measure call from OnLayout method in WrapperView.cs
  • Relies on base class measurement instead of performing additional measurement

Comment thread src/Core/src/Platform/Android/WrapperView.cs
@bcaceiro

Copy link
Copy Markdown

This will affect the perfomance rendering of all Views? 👯‍♂️

@albyrock87

Copy link
Copy Markdown
Contributor

This will affect the performance rendering of all Views? 👯‍♂️

My bet is that the removal of this code is probably gonna fix some weird behavior.

For example a measure in a VerticalStackLayout has infinite height constraint, but the layout method always provides a finite frame with a finite height.

Also this neutralizes the Android's measure caching mechanism.

So yeah, I believe this will bring a good improvement even on performance, but keep in mind that this is only related to wrapper view which comes into play only under some conditions (like Shadow or ClipsToBounds).

@albyrock87

albyrock87 commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

This seems a real failure (Issue23333), but as I mentioned before, your changes make sense, so there must be a mistake somewhere else which you just revealed @PureWeen.
Such test uses Frame and I even see that it's missing the shadow (while it's there on iOS and maccatalyst, but missing again on Windows).

Original New
image image

@kubaflo kubaflo changed the base branch from net10.0 to main May 6, 2026 13:07
@kubaflo

kubaflo commented May 6, 2026

Copy link
Copy Markdown
Contributor

/rebase

@github-actions github-actions Bot force-pushed the fix_wrapperview_measure_arrange branch from 291afda to c2d3160 Compare May 6, 2026 13:09
@kubaflo

kubaflo commented May 24, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml

@kubaflo

kubaflo commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

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

@MauiBot MauiBot added 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 Jun 6, 2026
MauiBot

This comment was marked as outdated.

@kubaflo

kubaflo commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

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

@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 — 1 findings

See inline comments for details.

var heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(bottom - top);

child.Measure(widthMeasureSpec, heightMeasureSpec);
child.Layout(0, 0, child.MeasuredWidth, child.MeasuredHeight);

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.

[warning] Measure/layout mismatch risk

After removing the exact child.Measure(...) call, this layout now trusts child.MeasuredWidth / child.MeasuredHeight from the prior measure pass. PlatformWrapperView.onMeasure() normally keeps those in sync, but Android can still call layout with final right - left / bottom - top bounds that differ from the cached measured size. If that happens, the child, border overlay, clip path, and shadow bitmap can be laid out/drawn at stale dimensions. Please either add targeted Android coverage proving the wrapper cannot receive divergent final bounds here, or keep the performance win while guarding the divergent case with a conditional exact remeasure.

@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

@PureWeen — new AI review results are available based on this last commit: c2d3160.
Remove excessive measure call To request a fresh review after new comments or commits, comment /review rerun.

Gate Skipped Code Review In Review Confidence Medium Platform Android Implementation Change

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

Gate Result: ⚠️ SKIPPED

No tests were detected in this PR.

Recommendation: Add tests to verify the fix using the write-tests-agent.


UI Tests — ViewBaseTests

Detected UI test categories: ViewBaseTests

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

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
ViewBaseTests 13/112 (99 ❌) 99 diff PNGs
ViewBaseTests — 99 failed tests
VisualTransform_AnchorXWithAnchorY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_AnchorXWithAnchorY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_AnchorXWithAnchorY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See te
...
VisualTransform_RotationWithScale
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_RotationWithScale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_RotationWithScale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test
...
VisualTransform_Scale
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_Scale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_Scale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download 
...
LightTheme_Editor_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_Editor_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 276
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at Syste
...
ContentView_ClipWithNestedClippedContent
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ContentView_ClipWithNestedClippedContent() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 971
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.R
...
ContentView_ClipWithRoundRectangleGeometry
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ContentView_ClipWithRoundRectangleGeometry() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 565
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System
...
DarkTheme_Editor_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_Editor_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 286
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System
...
Border_ClipWithStrokeThickness
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithStrokeThickness() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 52
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.R
...
FirstCustomPageWithIconImageChanged
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ContentViewFeatureTests.FirstCustomPageWithIconImageChanged() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs:line 274
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at
...
VisualTransform_AnchorY_ScaleWithRotationY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_AnchorY_ScaleWithRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_AnchorY_ScaleWithRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseli
...
Border_ClipWithRotation
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithRotation() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 835
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runtime
...
Button_ClipWithImageSource
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Button_ClipWithImageSource() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 223
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runt
...
VisualTransform_ScaleWithAnchorXAndRotationY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_ScaleWithAnchorXAndRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_ScaleWithAnchorXAndRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the ba
...
DarkTheme_SearchBarAndPlaceholderColor_VerifyVisualState
System.InvalidOperationException : 
Snapshot different than baseline: DarkTheme_SearchBarAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_SearchBarAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a 
...
LightTheme_Switch_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_Switch_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 185
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Image_ClipWithComplexPolyBezierAndRotation
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithComplexPolyBezierAndRotation() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 1052
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at Syste
...
LightTheme_RadioButton_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_RadioButton_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 114
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
LightTheme_DatePicker_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_DatePicker_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 86
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
VisualTransform_RotationX
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_RotationX.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_RotationX.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or d
...
VisualTransform_RotationY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_RotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_RotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or d
...
DarkTheme_EntryAndPlaceholderColor_VerifyVisualState
System.InvalidOperationException : 
Snapshot different than baseline: DarkTheme_EntryAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_EntryAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), th
...
Image_ClipWithPolyQuadraticBezierSegmentPath
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithPolyQuadraticBezierSegmentPath() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 447
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at Syst
...
VerifyBackgroundColorCleared
System.InvalidOperationException : 
Snapshot different than baseline: VerifyBackgroundColorCleared.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyBackgroundColorCleared.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachmen
...
LightTheme_EntryAndPlaceholderColor_VerifyVisualState
System.InvalidOperationException : 
Snapshot different than baseline: LightTheme_EntryAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_EntryAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), 
...
VisualTransform_ScaleY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_ScaleY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_ScaleY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or downloa
...
SecondCustomPageWithFlowDirectionChanged
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ContentViewFeatureTests.SecondCustomPageWithFlowDirectionChanged() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs:line 333
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)

...
Border_ClipNull_NoCrash
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipNull_NoCrash() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 695
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runtime
...
Image_ClipWithBezierSegmentPath
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithBezierSegmentPath() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 383
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection
...
ContentView_ClipNull_NoCrash
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ContentView_ClipNull_NoCrash() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 785
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Ru
...
ImageButton_ClipWithScale
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ImageButton_ClipWithScale() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 948
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runti
...

(+69 more — see TRX in artifact)

📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)


Pre-Flight — Context & Validation

Issue: #31769 - Remove excessive measure call
PR: #31769 - Remove excessive measure call
Platforms Affected: Android implementation change; requested testing platform: iOS (not an affected code path)
Files Changed: 1 implementation, 0 test

Key Findings

  • PR removes a redundant Android child.Measure(EXACTLY, EXACTLY) call from WrapperView.OnLayout; PlatformWrapperView.onMeasure() already measures the first child.
  • Prior discussion notes this may improve performance and avoid neutralizing Android measure caching, but an Android Frame/shadow scenario (Issue23333) reportedly exposed a visual failure.
  • Gate was already skipped because no tests were detected; no gate verification was rerun.
  • Requested test platform is iOS, but the changed file is Android-only (src/Core/src/Platform/Android/WrapperView.cs), so iOS execution cannot validate the behavior change.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: medium
Errors: 0 | Warnings: 1 | Suggestions: 0

Key code review findings:
src/Core/src/Platform/Android/WrapperView.cs:45 now assumes child.MeasuredWidth/Height match final allocation; targeted Android layout/shadow validation is still needed.-

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31769 Remove the redundant child.Measure call from Android WrapperView.OnLayout and rely on the child measurement performed by `PlatformWrapperView. SKIPPED (Gate: no tests detected) src/Core/src/Platform/Android/WrapperView.cs Original PR; no regression test included. onMeasure()`.

Code Review — Deep Analysis

Code PR #31769Review

Independent Assessment

What this changes: Removes the explicit Android child.Measure(EXACTLY, EXACTLY) call from WrapperView.OnLayout, using the echos existing measured size instead. child
Inferred motivation: PlatformWrapperView.onMeasure() already measures the child, so remeasuring during layout is redundant hot-path work.

Reconciliation with PR Narrative

Author claims: Base Java wrapper already measures the child.
Agreement/disagreement: Agreed for normal MAUI layout flow. Remaining risk is empirical Android Frame/shadow behavior and measured-size vs final-allocation edge cases.

Findings

Measure/layout mismatch riskWarning ####
src/Core/src/Platform/Android/WrapperView.cs:45 now assumes child.MeasuredWidth/Height match final allocation. Likely OK for echos normal path, but targeted Android layout/shadow validation is still needed.MAUI

Devil's Advocate

The change is probably architecturally correct and performance-positive. Re-adding the removed measure would defeat the echos purpose. The concern is validation uncertainty, not a proven bug.PR

Verdict: NEEDS_DISCUSSION

Confidence: medium
Summary: CI is not green, and Android Frame/shadow validation remains unresolved. Local artifacts written under CustomAgentLogsTmp/PRState/31769/PRAgent/; no GitHub comments posted.


Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Arrange child and border to final allocated wrapper bounds without measuring in ` BLOCKED / NOT EXERCISED 1 file iOS command succeeded but matched 0 tests and cannot exercise Android-only code. Viable but may arrange some Android controls to a size different from their last measure. OnLayout`.
2 try-fix Move supplemental measurement to OnMeasure for _borderView only; remove layout-time child BLOCKED / NOT EXERCISED 1 file Targets the overlay child that Java PlatformWrapperView.onMeasure() does not measure. Weaker because border measure/layout dimensions can diverge. measurement.
3 try-fix Skip layout-time measure when cached measured size matches final bounds; exact-measure only on BLOCKED / NOT EXERCISED 1 file Strongest surgical alternative: preserves common-path performance while guarding stale measured-size layout. Needs Android regression coverage. divergence.
PR PR #31769 Remove the redundant child.Measure call from Android WrapperView.OnLayout and rely on `PlatformWrapperView. SKIPPED (Gate: no tests detected) 1 file Original PR; no regression test included. onMeasure()`.

Cross-Pollination

Model Round New Ideas? Details
maui-expert-reviewer 1 Yes Replace _borderView child overlay with wrapper-owned drawing/foreground drawable so WrapperView remains a single-child container. Rejected as a try-fix candidate because it is a broad border-rendering architecture change, not a surgical alternative to the redundant measure call.

Exhausted: Yes for surgical alternatives. The only new idea found is a larger architecture rewrite outside the safe scope of this PR.
Selected Fix: Candidate #3 (conditional exact measure preferred by expert review on correctness/performance tradeoff, but not demonstrably validated because the requested iOS run matched zero tests and the code path is Android-only. Android wrapper regression coverage is required before recommending it over the PR fix.fallback)

Testing Notes

  • Gate result was pre-supplied as skipped because no tests were detected; gate verification was not rerun.
  • Requested platform was iOS. src/Core/src/Platform/Android/WrapperView.cs is Android-only, so iOS validation cannot exercise the modified code.
  • The command pwsh .github/scripts/BuildAndRunHostApp.ps1 -Platform ios -TestFilter "WrapperView" completed successfully for each candidate, but the test log says: No test matches the given testcase filter 'WrapperView'.

Failure / Blocker Analysis

No candidate failed behaviorally; all are blocked from meaningful validation by the platform/test mismatch. The most important follow-up is an Android regression test covering a wrapper with border/shadow/clip whose final layout bounds differ from its cached measured size.


Report — Final Recommendation

Comparative Report - PR #31769

Candidates compared

Rank Candidate Result status Assessment
1 pr-plus-reviewer Not meaningfully exercised; iOS run cannot cover Android-only code Best correctness/performance tradeoff. It keeps the PR's hot-path improvement for normal measure/layout passes and applies reviewer feedback by conditionally exact-measuring only when cached child dimensions diverge from final wrapper allocation.
2 try-fix-3 Blocked / not exercised Functionally the same conditional exact-measure fallback as pr-plus-reviewer. Strong standalone candidate, but ranked below pr-plus-reviewer because the reviewer-applied PR candidate preserves the PR path while addressing the same issue.
3 try-fix-1 Blocked / not exercised Removes the layout-time measure and lays out child/border to final allocated wrapper bounds. This avoids stale layout dimensions, but may arrange Android controls to dimensions that were not the dimensions from their last measure pass.
4 pr Gate skipped; no tests detected Minimal and performance-positive, but leaves the reviewer-identified mismatch risk unresolved and has no Android regression coverage.
5 try-fix-2 Blocked / not exercised Measures _borderView during OnMeasure, addressing the unmeasured border overlay, but keeps a weaker consistency story because the border can be measured to wrapper dimensions and then laid out to child measured dimensions.

Regression-test weighting

No candidate failed regression tests. All STEP 5a try-fix candidates were blocked from meaningful validation because the requested platform was iOS while the changed code is Android-only; the iOS command matched zero WrapperView tests. The raw PR gate was also skipped because no tests were detected. Therefore, no failing candidate had to be ranked below a passing candidate; the ranking is based on code-risk reduction and consistency with Android measure/layout semantics.

Analysis

The raw PR correctly removes redundant child.Measure(EXACTLY, EXACTLY) work from OnLayout, relying on PlatformWrapperView.onMeasure() to measure the first child. That is desirable on a layout hot path. The unresolved issue is that the raw PR still lays out the child and _borderView to cached MeasuredWidth / MeasuredHeight, so a final layout allocation that differs from the prior measure can leave child layout, border overlay, clip, and shadow drawing at stale dimensions.

try-fix-1 avoids stale dimensions by arranging to final allocated bounds, but it does so without making the child's measured dimensions match those bounds. try-fix-2 explores the second-child border-overlay issue, but its implemented measure/layout dimensions can diverge. try-fix-3 is the strongest independent alternative because it skips redundant work when the measure/layout contract holds and exact-measures only when it does not.

The expert-review feedback applied to the PR produces the same conditional fallback as try-fix-3, so pr-plus-reviewer wins: it retains the PR's performance goal, addresses the actionable reviewer warning, and is the lowest-risk implementation among candidates that have no meaningful test validation.

Winning candidate

Winner: pr-plus-reviewer

Rationale: It is the raw PR fix plus the only actionable reviewer correction. It removes redundant layout-time measurement on the common path while preserving correctness if Android delivers final wrapper bounds that differ from the cached measured child size. Android regression coverage for wrapper border/shadow/clip with divergent final bounds should still be added because no candidate was meaningfully exercised by the requested iOS validation.


Future Action — review latest findings

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

@kubaflo

kubaflo commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

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

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

🤖 Multi-model code review — Request changes

Three models reviewed this PR independently (Claude Opus 4.8, GPT-5.5, Gemini 3.1 Pro), then reconciled their findings in a cross-pollination round. This is an automated review summary; treat it as input, not a gate.

Consensus verdict: ❌ Request changes (all three independent reviewers flagged the same layout-correctness regression).

Core issue — the removed Measure is load-bearing

The deleted child.Measure(Exactly(right-left), Exactly(bottom-top)) forced the wrapped child to the wrapper's final arranged size before child.Layout(...). The Java base PlatformWrapperView.onMeasure measures the child with the cross-platform spec (often AT_MOST/Unspecified — e.g. infinite height inside a VerticalStackLayout), and Android's arrange path (PlatformArrangeHandler) only calls Layout(...), never re-measuring to the final frame. So child.MeasuredWidth/Height can be the desired size, not the arranged frame; laying the child + _borderView/shadow out at that stale size causes under-fill, clipping, and mis-sized borders/shadows under Fill alignment or infinite-constraint parents. The same file documents this exact principle in PrepareForTextViewArrange. See inline comments on lines 45–46.

Corroborating evidence

  • Confirmed regression: @albyrock87 already identified Issue23333 failing with the shadow missing (before/after screenshots in this thread) — the precise symptom predicted by the code analysis.
  • History: this re-measure is long-standing — it traces to the original container-view support (#1025) and was deliberately preserved when OnMeasure moved into Java (#14275). It is not dead code.
  • CI: the latest run is broadly red — every Android Controls UITest category, the CoreClr/Material3 variants, an iOS CollectionView leg, a macOS ListView leg, and device tests all fail; the branch is also ~9 months old. CI must be triaged and the branch rebased; a review cannot sign off while required checks are red.

What's needed before merge

  1. Restore the OnLayout re-measure (with the clarifying comment you offered), or guard it to run only when the arranged size != measured size — so the child/border/shadow are sized to the final frame.
  2. If the goal is to fix the underlying arrange-sizing path instead (per @albyrock87's "reveals a mistake elsewhere"), do that explicitly rather than deleting the guard at c2d3160.
  3. Add a regression test for a Shadow/Border wrapped element under Fill inside an infinite-constraint parent (e.g. VerticalStackLayout), and confirm Issue23333 passes.
  4. Rebase onto current main and get CI green.

Independent verdicts: Opus 4.8 — NEEDS_CHANGES (high) · GPT-5.5 — NEEDS_CHANGES (medium) · Gemini 3.1 Pro — NEEDS_DISCUSSION (medium). After cross-pollination, all three converged on NEEDS_CHANGES (high confidence).

var heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(bottom - top);

child.Measure(widthMeasureSpec, heightMeasureSpec);
child.Layout(0, 0, child.MeasuredWidth, child.MeasuredHeight);

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.

❌ This deleted child.Measure(Exactly(right-left), Exactly(bottom-top)) is not redundant — it forced the wrapped child to the wrapper's final arranged size before child.Layout(...). The Java base PlatformWrapperView.onMeasure measures the child against the cross-platform measure spec, which is frequently AT_MOST/Unspecified (e.g. a child in a VerticalStackLayout gets an infinite height constraint), so child.MeasuredWidth/Height holds the desired size, not the final frame. On Android the arrange path (PlatformArrangeHandler in ViewHandlerExtensions.Android.cs) only calls platformView.Layout(...) and never re-measures to the final frame, so at OnLayout time child.MeasuredWidth/Height can differ from right-left/bottom-top. Without the re-measure, the child (and _borderView/shadow) is laid out at the stale/desired size → under-fill, clipping, or mis-sized border/shadow whenever the arranged size differs from the measured size (Fill alignment, infinite-constraint parents). The very same file documents this principle in PrepareForTextViewArrange ("…might have an Unspecified/AtMost measure spec … we need to measure it again with more exact/final sizes"). This re-measure is long-standing — it traces to the original container-view support (#1025) and was deliberately preserved when OnMeasure moved into Java (#14275) — so it is load-bearing, not dead code. @albyrock87 already confirmed a concrete regression on this PR — Issue23333 fails with the shadow missing — and the description is exploratory ("I'm not sure why we have an extra measure call"). Restore the re-measure (with the clarifying comment you offered), or guard it to run only when the arranged size != measured size, AND add a regression test before merge.


child.Measure(widthMeasureSpec, heightMeasureSpec);
child.Layout(0, 0, child.MeasuredWidth, child.MeasuredHeight);
_borderView?.Layout(0, 0, child.MeasuredWidth, child.MeasuredHeight);

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.

_borderView is laid out to child.MeasuredWidth/Height, and the Java shadow path derives the shadow drawable bounds from the child's laid-out box. Both therefore inherit the same stale measured size once the OnLayout re-measure is removed, so when the arranged frame differs from the measured size the border and shadow render at the wrong dimensions — exactly the missing/mis-sized shadow observed for Issue23333 in this thread. If the optimization is kept, the border/shadow must obtain the final arranged size (right-left/bottom-top) rather than relying on child.MeasuredWidth/Height.

@kubaflo

kubaflo commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

/review rerun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants