[Android] Fix RadialGradientBrush crash on Android when view has zero size - #35781
Conversation
… it) (dotnet#35714) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Follow-up to @kubaflo's review on dotnet#35687. ## What In `eng/pipelines/ci-copilot.yml`, when `parameters.Platform == 'android'`, the Android AVD was being created twice: 1. **First**, via `common/provision.yml` running the `ProvisionAndroidSdkAvdCreateAvds` MSBuild target — because `skipAndroidCreateAvds: ${{ ne(parameters.Platform, 'android') }}` evaluated to `false` for Android. That target invokes `dotnet android avd create --name "Emulator_30" … --force`. 2. **Then**, the inline `Create AVD and boot Android Emulator` script ran `avdmanager create avd -n Emulator_30 -k "system-images;android-30;google_apis_playstore;x86_64" --device "Nexus 5X" --force`. Both create the same AVD name with `--force`, so the second silently overwrites the first — no error, just ~30–60s wasted on every Copilot review pipeline run for Android. The inline script is the canonical source of truth: it pins the `google_apis_playstore` image variant, the `Nexus 5X` device profile, the `disk.dataPartition.size=2048m` shrink, and ADB key pre-auth. None of those are applied by `ProvisionAndroidSdkAvdCreateAvds`. So the right fix is to skip the provision step entirely and let the inline script own AVD creation. ## Change Pinned `skipAndroidCreateAvds: true` (with an explanatory comment) at both call sites of `common/provision.yml` in `ci-copilot.yml` (the ReviewPR stage and the Deep stage). The inline `avdmanager` blocks are untouched. This is the AVD-creation portion of dotnet#35376 being reverted — the inline script that same PR added already handles AVD creation, so the provision-step AVD creation was redundant. ## Scope This change is scoped to **`ci-copilot.yml`** only — the Copilot review pipeline. It does **not** touch the required gating pipelines: - `maui-pr` - `maui-pr-devicetests` - `maui-pr-uitests` ## Follow-up Needs to be ported to `net11.0` afterward via the automated `merge/main-to-net11.0` flow. Co-authored-by: bot <bot@test> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…authors (dotnet#35751) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Problem Two issues with the daily "PR Review Queue" automation: ### 1. Workflow runs in forks and creates duplicate tracking issues `.github/workflows/pr-review-queue.yml` had no fork guard, so the daily scheduled run (`cron: "0 8 * * 1-5"`) was firing in active forks of dotnet/maui as well as in upstream. The `gh issue create --repo ${{ github.repository }}` step targets the running repo, so each fork ended up with its own `[PR Review Queue]` issue alongside the legitimate dotnet/maui one — e.g. `PureWeen#105` and `dotnet#35732` for the same day, both pinging the fork owner. ### 2. Every PR author gets @-mentioned daily The markdown table emitted each PR author handle as a raw `@username`, which GitHub parses as a real mention. Each daily run created a new issue and notified every PR author — community contributors, partner devs, bots — even though the issue is purely an internal MAUI-team triage artifact. ## Changes **`.github/workflows/pr-review-queue.yml`** — Add the same `github.repository_owner == 'dotnet'` guard already used by 8 other dotnet-owned workflows in this repo (`backport.yml`, `rebase.yml`, `locker.yml`, `dogfood-comment.yml`, `maestro-changelog.yml`, `inclusive-heat-sensor.yml`, `dotnet-format-daily.yml`, `dotnet-autoformat-pr-push.yml`). Applied to both jobs: - `generate-report` — stops the scheduled issue creation on forks. - `validate` — stops fork-internal PRs from spending CI on the dry-run. **`.github/skills/find-reviewable-pr/scripts/query-reviewable-prs.ps1`** — Wrap author handles in backticks (`` `@username` ``) in all four table-row formats. GitHub does not parse mentions inside code spans, so no notifications fire, but the table still reads naturally as a list of author handles. ## Verification - YAML parses cleanly (`python3 -c "import yaml; yaml.safe_load(...)"`). - PowerShell escape verified — `"``@$($pr.Author)``"` renders as `` `@PureWeen` ``. - Existing renderer logic for `$showMilestone` / `$showTurn` variants left intact; only the author cell changed. ## Out of scope Other automation in this repo was checked and is already fork-safe: - The gh-aw `*.lock.yml` files (`agentic-labeler`, `daily-repo-status`, `copilot-evaluate-tests`) and `agentics-maintenance.yml` are auto-generated (`DO NOT EDIT`) and have their own pre-activation role checks. - `review-trigger.yml` is implicitly fork-safe via its actor-permission check. --------- Co-authored-by: bot <bot@test> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tartup crashes (dotnet#35724) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description PowerShell 7.4.x intermittently crashes at startup on macOS with: ``` Call to 'procargs' failed with errno 5 Unhandled exception. Microsoft.PowerShell.ManagedPSEntry+StartupException at Microsoft.PowerShell.ManagedPSEntry.ThrowOnFailure(String call, Int32 code) at Microsoft.PowerShell.ManagedPSEntry.AttemptExecPwshLogin(String[] args) at Microsoft.PowerShell.ManagedPSEntry.Main(String[] args) ``` This is [PowerShell/PowerShell#20802](PowerShell/PowerShell#20802) — open and untriaged since November 2023, **0 comments, no linked PRs, no fix shipped**. The crash happens in `AttemptExecPwshLogin`, which on macOS calls `sysctl(KERN_PROCARGS2)` to inspect its own `argv[0]` and decide whether pwsh was launched as a login shell. That `sysctl` call races intermittently and returns `errno 5`, aborting startup before pwsh reads any user script. ## Repro / impact Hit on the internal `dotnet-maui` pipeline (definition 1095), build **2990586**, during release-prep for `release/11.0.1xx-preview5`: > `##[section]Starting: Provision Android SDK - Common Packages` → `Call to 'procargs' failed with errno 5` → task fails with exit code `null`. A rerun on a different agent passed, but every macOS `pwsh:` / `PowerShell@2` step in the pipeline is a flake risk going forward. Inventory: ~57 pwsh tasks across 15 pipeline YAMLs, ~45 of them on macOS-eligible jobs. ## Fix PowerShell itself ships a short-circuit for this code path. From [`src/powershell/Program.cs`](https://github.com/PowerShell/PowerShell/blob/master/src/powershell/Program.cs): ```csharp private const string LOGIN_ENV_VAR_NAME = "__PWSH_LOGIN_CHECKED"; if (Environment.GetEnvironmentVariable(LOGIN_ENV_VAR_NAME) != null) { Environment.SetEnvironmentVariable(LOGIN_ENV_VAR_NAME, null); return; // ← skips the racy sysctl(KERN_PROCARGS2) entirely } ``` Setting `__PWSH_LOGIN_CHECKED=1` makes pwsh skip the racy syscall. This PR declares it as a pipeline-level variable in `eng/pipelines/common/variables.yml` (included by every macOS-touching pipeline — `ci.yml`, `ci-official.yml`, `ci-device-tests.yml`, `ci-copilot.yml`, `ci-uitests.yml`, `device-tests.yml`, `ui-tests.yml`, `handlers.yml`, etc.). Per [AzDO docs](https://learn.microsoft.com/azure/devops/pipelines/process/variables), user-defined variables are injected as environment variables for every task — so every `pwsh:` / `PowerShell@2` step in every job inherits it. ## Safety analysis This is safe because: - **CI never wants login-shell semantics.** No `-Login` flag, no leading `-` in `argv[0]`. The skipped code's `IsLogin()` check would have returned `false` and the function would have returned without doing anything visible. We just avoid the broken syscall that precedes that decision. - **The env var is single-use per process.** `AttemptExecPwshLogin` consumes it via `SetEnvironmentVariable(LOGIN_ENV_VAR_NAME, null)`, so nested `pwsh-launches-pwsh` scenarios still work normally (each new task gets a fresh AzDO-injected value). - **Windows is unaffected.** The read is inside a `#if UNIX` block; Windows pwsh ignores the var entirely. Setting it on Windows agents is a no-op. - **Safe even under `-Login`.** If a future step explicitly adds `-Login`, the short-circuit still routes around the broken syscall — the same syscall the login-shell *detection* relies on. So there's no regression even in that (currently nonexistent) use case. ## Empirical validation Verified locally on `pwsh 7.4.5` / macOS 26.5 (same 7.4.x minor as the CI agent that crashed): | Run | Command | Result | | --- | --- | --- | | Control | `pwsh ... -Command 'Write-Output "envvar=[$Env:__PWSH_LOGIN_CHECKED]"'` | `envvar=[]` (var unset; nothing to clear) | | Test | `__PWSH_LOGIN_CHECKED=1 pwsh ... -Command 'Write-Output "envvar=[$Env:__PWSH_LOGIN_CHECKED]"'` | `envvar=[]` ← **proves the short-circuit ran** (the only line that clears the var is inside the skip-path; if it cleared, the racy syscall was never reached) | | Soak | 100 × `__PWSH_LOGIN_CHECKED=1 pwsh ... -Command 'exit 0'` | **0/100 failures**; no behavioral change | ## Backport plan - This PR: `main` (.NET 10 SR dev). Drives the fix into ongoing servicing builds. - Will cherry-pick to `net11.0` afterward (where build 2990586 crashed during preview5 prep). Diff is verified to apply cleanly to both branches. ## Related macOS-agent flakes (out of scope) The same dnceng macOS agent pool has produced other, *unrelated* flakes during this release-prep window (e.g. `IDEDownloadableMetalToolchainCoordinator: Failed to remount` and `iOS 26.2 platform not installed` on builds 2990581 and 2990384). Those are agent-image issues and need agent-side fixes — they're not addressed here. This PR fixes one specific class of macOS flake (pwsh startup race), not all of them. Co-authored-by: bot <bot@test> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35781Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35781" |
|
Hey there @@SyedAbdulAzeemSF4852! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
/review -b feature/enhanced-reviewer |
…ch original C# semantics
kubaflo
left a comment
There was a problem hiding this comment.
Looks good; is this PR ready?
|
/review -b feature/enhanced-reviewer -p android |
yes @kubaflo. I also reviewed the MauiBot summary, which reported a gate failure on Android. I verified the test case locally and confirmed that it passes with the fix applied and fails without the fix.
|
|
/review tests |
|
/review rerun |
This comment has been minimized.
This comment has been minimized.
Tests Failure Analysis
✅ Test Failure Review: Likely unrelated - click to expandOverall verdict: Likely unrelated All build failures trace to a single pre-existing compile error in
Recommended actionNo changes needed in this PR. A separate fix is required on Evidence details
|
|
/review -b feature/enhanced-reviewer -p android |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
| return null; | ||
| } | ||
|
|
||
| if (width == 0 && height == 0) { |
There was a problem hiding this comment.
[major] Android graphics/platform API preconditions — This guard only handles the reported zero-width-and-height case, but Android RadialGradient throws whenever the computed radius is <= 0. A RadialGradientPaint can still produce radius 0 with non-zero bounds, for example when Radius is 0 or left at the default from constructors that don't initialize it, so this path will still reach new RadialGradient(..., this.gradientBounds[2] * Math.max(width, height), ...) and crash. Please guard the radial branch on the computed radius before constructing RadialGradient and add coverage for a zero-radius radial gradient.
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@SyedAbdulAzeemSF4852 — new AI review results are available based on this last commit:
232eafc.
Fix: Move zero-size guard to getShader() with && instead of || to match original C# semantics To request a fresh review after new comments or commits, comment/review rerun.
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) |
|---|---|---|
📱 GraphicsTests (RadialGradientWithZeroSizeDoesNotThrow) Category=Graphics |
✅ FAIL — 499s | ✅ PASS — 1285s |
🔴 Without fix — 📱 GraphicsTests (RadialGradientWithZeroSizeDoesNotThrow): FAIL ✅ · 499s
(truncated to last 15,000 chars)
er'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Editor'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Entry'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'FlowDirection'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'FlyoutView'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Fonts'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'GraphicsView'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Image'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'ImageButton'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'ImageSource'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'IndicatorView'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Label'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Layout'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'Memory'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.442 8139 8226 I DOTNET : [FILTER] Included test (filtered by Trait; 'Category':'NavigationPage'): [TimePicker] Font Attributes Initialize Correctly
06-10 13:20:38.464 8139 8226 I DOTNET : [Test environment: 64-bit .NET .NET 10.0 [collection-per-class, non-parallel]]
06-10 13:20:38.464 8139 8226 I DOTNET : [Test framework: xUnit.net 2.9.0.0]
06-10 13:20:38.480 8139 8226 I DOTNET : Test collection for Microsoft.Maui.DeviceTests.GraphicsTests
06-10 13:20:38.552 8139 8226 I DOTNET : [PASS] PointImplicitConversionTest
06-10 13:20:38.563 8139 8226 I DOTNET : [PASS] PointImplicitConversionTest
06-10 13:20:38.568 8139 8226 I DOTNET : [PASS] PointExplicitConversionTest
06-10 13:20:38.568 8139 8226 I DOTNET : [PASS] PointExplicitConversionTest
06-10 13:20:38.579 8139 8226 I DOTNET : [PASS] PointFImplicitConversionTest
06-10 13:20:38.579 8139 8226 I DOTNET : [PASS] PointFImplicitConversionTest
06-10 13:20:38.583 8139 8226 I DOTNET : [PASS] PointFExplicitConversionTest
06-10 13:20:38.583 8139 8226 I DOTNET : [PASS] PointFExplicitConversionTest
06-10 13:20:38.594 8139 8226 I DOTNET : [PASS] PointFExplicitConversionTest
06-10 13:20:38.594 8139 8226 I DOTNET : [PASS] PointFExplicitConversionTest
06-10 13:20:38.617 8139 8226 I DOTNET : Test name: RadialGradientWithZeroSizeDoesNotThrow
06-10 13:20:38.619 8139 8226 I DOTNET : Exception messages: Assert.Null() Failure: Value is not null
06-10 13:20:38.619 8139 8226 I DOTNET : Expected: null
06-10 13:20:38.619 8139 8226 I DOTNET : Actual: Java.Lang.IllegalArgumentException: radius must be > 0
06-10 13:20:38.619 8139 8226 I DOTNET : at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* )
06-10 13:20:38.619 8139 8226 I DOTNET : at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
06-10 13:20:38.619 8139 8226 I DOTNET : at Android.Graphics.Drawables.ShapeDrawable.Draw(Canvas )
06-10 13:20:38.619 8139 8226 I DOTNET : at Microsoft.Maui.DeviceTests.GraphicsTests.<>c__DisplayClass0_0.<RadialGradientWithZeroSizeDoesNotThrow>b__0()
06-10 13:20:38.619 8139 8226 I DOTNET : at Xunit.Record.Exception(Action testCode)
06-10 13:20:38.619 8139 8226 I DOTNET : --- End of managed Java.Lang.IllegalArgumentException stack trace ---
06-10 13:20:38.619 8139 8226 I DOTNET : java.lang.IllegalArgumentException: radius must be > 0
06-10 13:20:38.619 8139 8226 I DOTNET : at android.graphics.RadialGradient.<init>(RadialGradient.java:104)
06-10 13:20:38.619 8139 8226 I DOTNET : at android.graphics.RadialGradient.<init>(RadialGradient.java:67)
06-10 13:20:38.619 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawableStyle.getShader(PlatformDrawableStyle.java:82)
06-10 13:20:38.619 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawableStyle.applyStyle(PlatformDrawableStyle.java:111)
06-10 13:20:38.619 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawable.onDraw(PlatformDrawable.java:200)
06-10 13:20:38.619 8139 8226 I DOTNET : at android.graphics.drawable.ShapeDrawable.draw(ShapeDrawable.java:252)
06-10 13:20:38.620 8139 8226 I DOTNET : Exception stack traces: at Microsoft.Maui.DeviceTests.GraphicsTests.RadialGradientWithZeroSizeDoesNotThrow()
06-10 13:20:38.620 8139 8226 I DOTNET : at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
06-10 13:20:38.620 8139 8226 I DOTNET : at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object , BindingFlags )
06-10 13:20:38.620 8139 8226 I DOTNET : Execution time: 0.0185963
06-10 13:20:38.620 8139 8226 I DOTNET : Test trait name: Category
06-10 13:20:38.620 8139 8226 I DOTNET : value: Graphics
06-10 13:20:38.620 8139 8226 I DOTNET : value: Graphics
06-10 13:20:38.620 8139 8226 I DOTNET : [FAIL] RadialGradientWithZeroSizeDoesNotThrow
06-10 13:20:38.620 8139 8226 I DOTNET : [FAIL] RadialGradientWithZeroSizeDoesNotThrow Test name: RadialGradientWithZeroSizeDoesNotThrow
06-10 13:20:38.620 8139 8226 I DOTNET : Assembly: [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
06-10 13:20:38.620 8139 8226 I DOTNET : Exception messages: Assert.Null() Failure: Value is not null
06-10 13:20:38.620 8139 8226 I DOTNET : Expected: null
06-10 13:20:38.620 8139 8226 I DOTNET : Actual: Java.Lang.IllegalArgumentException: radius must be > 0
06-10 13:20:38.620 8139 8226 I DOTNET : at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* )
06-10 13:20:38.620 8139 8226 I DOTNET : at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
06-10 13:20:38.620 8139 8226 I DOTNET : at Android.Graphics.Drawables.ShapeDrawable.Draw(Canvas )
06-10 13:20:38.620 8139 8226 I DOTNET : at Microsoft.Maui.DeviceTests.GraphicsTests.<>c__DisplayClass0_0.<RadialGradientWithZeroSizeDoesNotThrow>b__0()
06-10 13:20:38.620 8139 8226 I DOTNET : at Xunit.Record.Exception(Action testCode)
06-10 13:20:38.620 8139 8226 I DOTNET : --- End of managed Java.Lang.IllegalArgumentException stack trace ---
06-10 13:20:38.620 8139 8226 I DOTNET : java.lang.IllegalArgumentException: radius must be > 0
06-10 13:20:38.620 8139 8226 I DOTNET : at android.graphics.RadialGradient.<init>(RadialGradient.java:104)
06-10 13:20:38.620 8139 8226 I DOTNET : at android.graphics.RadialGradient.<init>(RadialGradient.java:67)
06-10 13:20:38.620 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawableStyle.getShader(PlatformDrawableStyle.java:82)
06-10 13:20:38.620 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawableStyle.applyStyle(PlatformDrawableStyle.java:111)
06-10 13:20:38.620 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawable.onDraw(PlatformDrawable.java:200)
06-10 13:20:38.620 8139 8226 I DOTNET : at android.graphics.drawable.ShapeDrawable.draw(ShapeDrawable.java:252)
06-10 13:20:38.620 8139 8226 I DOTNET : Exception stack traces: at Microsoft.Maui.DeviceTests.GraphicsTests.RadialGradientWithZeroSizeDoesNotThrow()
06-10 13:20:38.620 8139 8226 I DOTNET : at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
06-10 13:20:38.620 8139 8226 I DOTNET : at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object , BindingFlags )
06-10 13:20:38.620 8139 8226 I DOTNET : Execution time: 0.0185963
06-10 13:20:38.620 8139 8226 I DOTNET : Test trait name: Category
06-10 13:20:38.620 8139 8226 I DOTNET : value: Graphics
06-10 13:20:38.620 8139 8226 I DOTNET : value: Graphics
06-10 13:20:38.620 8139 8226 I DOTNET :
06-10 13:20:38.627 8139 8226 I DOTNET : [PASS] RectImplicitConversionTest
06-10 13:20:38.627 8139 8226 I DOTNET : [PASS] RectImplicitConversionTest
06-10 13:20:38.632 8139 8226 I DOTNET : [PASS] RectFExplicitConversionTest
06-10 13:20:38.633 8139 8226 I DOTNET : [PASS] RectFExplicitConversionTest
06-10 13:20:38.642 8139 8226 I DOTNET : [PASS] RectExplicitConversionTest
06-10 13:20:38.642 8139 8226 I DOTNET : [PASS] RectExplicitConversionTest
06-10 13:20:38.646 8139 8226 I DOTNET : [PASS] RectFImplicitConversionTest
06-10 13:20:38.647 8139 8226 I DOTNET : [PASS] RectFImplicitConversionTest
06-10 13:20:38.649 8139 8226 I DOTNET : Microsoft.Maui.DeviceTests.GraphicsTests 0.0546285 ms
06-10 13:20:38.660 8139 8226 I DOTNET : Failed tests:
06-10 13:20:38.660 8139 8226 I DOTNET : 1) [FAIL] RadialGradientWithZeroSizeDoesNotThrow Test name: RadialGradientWithZeroSizeDoesNotThrow
06-10 13:20:38.660 8139 8226 I DOTNET : Assembly: [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
06-10 13:20:38.660 8139 8226 I DOTNET : Exception messages: Assert.Null() Failure: Value is not null
06-10 13:20:38.660 8139 8226 I DOTNET : Expected: null
06-10 13:20:38.660 8139 8226 I DOTNET : Actual: Java.Lang.IllegalArgumentException: radius must be > 0
06-10 13:20:38.660 8139 8226 I DOTNET : at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(JniObjectReference , JniObjectReference , JniMethodInfo , JniArgumentValue* )
06-10 13:20:38.660 8139 8226 I DOTNET : at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
06-10 13:20:38.660 8139 8226 I DOTNET : at Android.Graphics.Drawables.ShapeDrawable.Draw(Canvas )
06-10 13:20:38.660 8139 8226 I DOTNET : at Microsoft.Maui.DeviceTests.GraphicsTests.<>c__DisplayClass0_0.<RadialGradientWithZeroSizeDoesNotThrow>b__0()
06-10 13:20:38.660 8139 8226 I DOTNET : at Xunit.Record.Exception(Action testCode)
06-10 13:20:38.660 8139 8226 I DOTNET : --- End of managed Java.Lang.IllegalArgumentException stack trace ---
06-10 13:20:38.660 8139 8226 I DOTNET : java.lang.IllegalArgumentException: radius must be > 0
06-10 13:20:38.660 8139 8226 I DOTNET : at android.graphics.RadialGradient.<init>(RadialGradient.java:104)
06-10 13:20:38.660 8139 8226 I DOTNET : at android.graphics.RadialGradient.<init>(RadialGradient.java:67)
06-10 13:20:38.660 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawableStyle.getShader(PlatformDrawableStyle.java:82)
06-10 13:20:38.660 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawableStyle.applyStyle(PlatformDrawableStyle.java:111)
06-10 13:20:38.660 8139 8226 I DOTNET : at com.microsoft.maui.PlatformDrawable.onDraw(PlatformDrawable.java:200)
06-10 13:20:38.660 8139 8226 I DOTNET : at android.graphics.drawable.ShapeDrawable.draw(ShapeDrawable.java:252)
06-10 13:20:38.660 8139 8226 I DOTNET : Exception stack traces: at Microsoft.Maui.DeviceTests.GraphicsTests.RadialGradientWithZeroSizeDoesNotThrow()
06-10 13:20:38.660 8139 8226 I DOTNET : at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
06-10 13:20:38.660 8139 8226 I DOTNET : at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object , BindingFlags )
06-10 13:20:38.660 8139 8226 I DOTNET : Execution time: 0.0185963
06-10 13:20:38.660 8139 8226 I DOTNET : Test trait name: Category
06-10 13:20:38.660 8139 8226 I DOTNET : value: Graphics
06-10 13:20:38.660 8139 8226 I DOTNET : value: Graphics
06-10 13:20:38.660 8139 8226 I DOTNET :
06-10 13:20:38.683 8139 8226 I DOTNET : Xml file was written to the provided writer.
06-10 13:20:38.683 8139 8226 I DOTNET : Tests run: 1320 Passed: 48 Inconclusive: 0 Failed: 1 Ignored: 1271
�[41m�[30mfail�[39m�[22m�[49m: Non-success instrumentation exit code: 1, expected: 0
�[40m�[32minfo�[39m�[22m�[49m: <<XHARNESS_RESULT_START>>
{
"version": 1,
"machineName": "runnervm32qxw",
"exitCode": 1,
"exitCodeName": "TESTS_FAILED",
"platform": "android",
"instrumentationExitCode": 1,
"device": "emulator-5554",
"deviceOsVersion": "API 30",
"architecture": "x86_64",
"files": [
{
"name": "testResults.xml",
"type": "test-results"
},
{
"name": "adb-logcat-com.microsoft.maui.core.devicetests-default.log",
"type": "logcat"
}
]
}
<<XHARNESS_RESULT_END>>
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.core.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.core.devicetests'
�[40m�[32minfo�[39m�[22m�[49m: Successfully uninstalled com.microsoft.maui.core.devicetests
XHarness exit code: 1 (TESTS_FAILED)
Tests completed with exit code: 1
🟢 With fix — 📱 GraphicsTests (RadialGradientWithZeroSizeDoesNotThrow): PASS ✅ · 1285s
(truncated to last 15,000 chars)
.Jvm.dll -> Xamarin.AndroidX.Lifecycle.Common.Jvm.dll.so
[113/128] System.Text.Encodings.Web.dll -> System.Text.Encodings.Web.dll.so
[43/128] Xamarin.AndroidX.Lifecycle.LiveData.Core.dll -> Xamarin.AndroidX.Lifecycle.LiveData.Core.dll.so
[44/128] Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModel.Android.dll.so
[45/128] Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll -> Xamarin.AndroidX.Lifecycle.ViewModelSavedState.Android.dll.so
[114/128] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
[46/128] Xamarin.AndroidX.Loader.dll -> Xamarin.AndroidX.Loader.dll.so
[115/128] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
[47/128] Xamarin.AndroidX.Navigation.Common.Android.dll -> Xamarin.AndroidX.Navigation.Common.Android.dll.so
[116/128] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
[48/128] Xamarin.AndroidX.Navigation.Fragment.dll -> Xamarin.AndroidX.Navigation.Fragment.dll.so
[117/128] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
[118/128] System.Text.Json.dll -> System.Text.Json.dll.so
[49/128] Xamarin.AndroidX.Navigation.Runtime.Android.dll -> Xamarin.AndroidX.Navigation.Runtime.Android.dll.so
[119/128] System.Threading.dll -> System.Threading.dll.so
[120/128] System.Xml.Linq.dll -> System.Xml.Linq.dll.so
[50/128] Xamarin.AndroidX.Navigation.UI.dll -> Xamarin.AndroidX.Navigation.UI.dll.so
[121/128] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
[122/128] System.Xml.ReaderWriter.dll -> System.Xml.ReaderWriter.dll.so
[123/128] System.dll -> System.dll.so
[124/128] netstandard.dll -> netstandard.dll.so
[51/128] Xamarin.AndroidX.RecyclerView.dll -> Xamarin.AndroidX.RecyclerView.dll.so
[125/128] Mono.Android.Runtime.dll -> Mono.Android.Runtime.dll.so
[52/128] Xamarin.AndroidX.SavedState.SavedState.Android.dll -> Xamarin.AndroidX.SavedState.SavedState.Android.dll.so
[53/128] Xamarin.AndroidX.SwipeRefreshLayout.dll -> Xamarin.AndroidX.SwipeRefreshLayout.dll.so
[126/128] Java.Interop.dll -> Java.Interop.dll.so
[54/128] Xamarin.AndroidX.ViewPager.dll -> Xamarin.AndroidX.ViewPager.dll.so
[55/128] Xamarin.AndroidX.ViewPager2.dll -> Xamarin.AndroidX.ViewPager2.dll.so
[56/128] Xamarin.Google.Android.Material.dll -> Xamarin.Google.Android.Material.dll.so
[57/128] Xamarin.Kotlin.StdLib.dll -> Xamarin.Kotlin.StdLib.dll.so
[58/128] Xamarin.KotlinX.Coroutines.Core.Jvm.dll -> Xamarin.KotlinX.Coroutines.Core.Jvm.dll.so
[59/128] Xamarin.KotlinX.Serialization.Core.Jvm.dll -> Xamarin.KotlinX.Serialization.Core.Jvm.dll.so
[127/128] Mono.Android.dll -> Mono.Android.dll.so
[60/128] xunit.abstractions.dll -> xunit.abstractions.dll.so
[61/128] xunit.assert.dll -> xunit.assert.dll.so
[62/128] xunit.core.dll -> xunit.core.dll.so
[63/128] xunit.execution.dotnet.dll -> xunit.execution.dotnet.dll.so
[64/128] xunit.runner.utility.netcoreapp10.dll -> xunit.runner.utility.netcoreapp10.dll.so
[65/128] System.Collections.Concurrent.dll -> System.Collections.Concurrent.dll.so
[66/128] System.Collections.Immutable.dll -> System.Collections.Immutable.dll.so
[67/128] System.Collections.NonGeneric.dll -> System.Collections.NonGeneric.dll.so
[68/128] System.Collections.Specialized.dll -> System.Collections.Specialized.dll.so
[69/128] System.Collections.dll -> System.Collections.dll.so
[70/128] System.ComponentModel.Primitives.dll -> System.ComponentModel.Primitives.dll.so
[71/128] System.ComponentModel.TypeConverter.dll -> System.ComponentModel.TypeConverter.dll.so
[72/128] System.ComponentModel.dll -> System.ComponentModel.dll.so
[73/128] System.Console.dll -> System.Console.dll.so
[128/128] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
[74/128] System.Diagnostics.Debug.dll -> System.Diagnostics.Debug.dll.so
[75/128] System.Diagnostics.DiagnosticSource.dll -> System.Diagnostics.DiagnosticSource.dll.so
[76/128] System.Diagnostics.Process.dll -> System.Diagnostics.Process.dll.so
[77/128] System.Diagnostics.Tools.dll -> System.Diagnostics.Tools.dll.so
[78/128] System.Diagnostics.TraceSource.dll -> System.Diagnostics.TraceSource.dll.so
[79/128] System.Diagnostics.Tracing.dll -> System.Diagnostics.Tracing.dll.so
[80/128] System.Drawing.Primitives.dll -> System.Drawing.Primitives.dll.so
[81/128] System.Drawing.dll -> System.Drawing.dll.so
[82/128] System.Formats.Asn1.dll -> System.Formats.Asn1.dll.so
[83/128] System.Globalization.dll -> System.Globalization.dll.so
[84/128] System.IO.Compression.Brotli.dll -> System.IO.Compression.Brotli.dll.so
[85/128] System.IO.Compression.dll -> System.IO.Compression.dll.so
[86/128] System.IO.FileSystem.dll -> System.IO.FileSystem.dll.so
[87/128] System.IO.Pipelines.dll -> System.IO.Pipelines.dll.so
[88/128] System.IO.dll -> System.IO.dll.so
[89/128] System.Linq.Expressions.dll -> System.Linq.Expressions.dll.so
[90/128] System.Linq.dll -> System.Linq.dll.so
[91/128] System.Memory.dll -> System.Memory.dll.so
[92/128] System.Net.Http.dll -> System.Net.Http.dll.so
[93/128] System.Net.NameResolution.dll -> System.Net.NameResolution.dll.so
[94/128] System.Net.Primitives.dll -> System.Net.Primitives.dll.so
[95/128] System.Net.Requests.dll -> System.Net.Requests.dll.so
[96/128] System.Net.Sockets.dll -> System.Net.Sockets.dll.so
[97/128] System.Numerics.Vectors.dll -> System.Numerics.Vectors.dll.so
[98/128] System.ObjectModel.dll -> System.ObjectModel.dll.so
[99/128] System.Private.Uri.dll -> System.Private.Uri.dll.so
[100/128] System.Private.Xml.Linq.dll -> System.Private.Xml.Linq.dll.so
[101/128] System.Private.Xml.dll -> System.Private.Xml.dll.so
[102/128] System.Reflection.Extensions.dll -> System.Reflection.Extensions.dll.so
[103/128] System.Reflection.TypeExtensions.dll -> System.Reflection.TypeExtensions.dll.so
[104/128] System.Reflection.dll -> System.Reflection.dll.so
[105/128] System.Runtime.Extensions.dll -> System.Runtime.Extensions.dll.so
[106/128] System.Runtime.InteropServices.RuntimeInformation.dll -> System.Runtime.InteropServices.RuntimeInformation.dll.so
[107/128] System.Runtime.InteropServices.dll -> System.Runtime.InteropServices.dll.so
[108/128] System.Runtime.Loader.dll -> System.Runtime.Loader.dll.so
[109/128] System.Runtime.Numerics.dll -> System.Runtime.Numerics.dll.so
[110/128] System.Runtime.dll -> System.Runtime.dll.so
[111/128] System.Security.Cryptography.dll -> System.Security.Cryptography.dll.so
[112/128] System.Text.Encoding.dll -> System.Text.Encoding.dll.so
[113/128] System.Text.Encodings.Web.dll -> System.Text.Encodings.Web.dll.so
[114/128] System.Text.Json.dll -> System.Text.Json.dll.so
[115/128] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
[116/128] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
[117/128] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
[118/128] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
[119/128] System.Threading.dll -> System.Threading.dll.so
[120/128] System.Xml.Linq.dll -> System.Xml.Linq.dll.so
[121/128] System.Xml.ReaderWriter.dll -> System.Xml.ReaderWriter.dll.so
[122/128] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
[123/128] System.dll -> System.dll.so
[124/128] netstandard.dll -> netstandard.dll.so
[125/128] Java.Interop.dll -> Java.Interop.dll.so
[126/128] Mono.Android.Runtime.dll -> Mono.Android.Runtime.dll.so
[127/128] Mono.Android.dll -> Mono.Android.dll.so
[128/128] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:07:12.33
[11.0.0-prerelease.26230.4+92962e5c46ac08a66ded4c5696209cc60f1a232f] XHarness command issued: android test --app /home/vsts/work/1/s/artifacts/bin/Core.DeviceTests/Release/net10.0-android/com.microsoft.maui.core.devicetests-Signed.apk --package-name com.microsoft.maui.core.devicetests --device-id emulator-5554 -o artifacts/log --timeout 01:00:00 -v --arg TestFilter=Category=Graphics
�[40m�[37mdbug�[39m�[22m�[49m: ADBRunner using ADB.exe supplied from /home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/tools/net10.0/any/../../../runtimes/any/native/adb/linux/adb
�[40m�[37mdbug�[39m�[22m�[49m: Full resolved path:'/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb'
�[40m�[32minfo�[39m�[22m�[49m: Will attempt to find device supporting architectures: 'arm64-v8a', 'x86_64'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb start-server'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[32minfo�[39m�[22m�[49m: Finding attached devices/emulators...
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb devices -l'
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 possible devices
�[40m�[37mdbug�[39m�[22m�[49m: Evaluating output line for device serial: emulator-5554 device product:sdk_gphone_x86_64 model:sdk_gphone_x86_64 device:generic_x86_64_arm64 transport_id:2
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell getprop ro.product.cpu.abilist'
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 possible devices. Using 'emulator-5554'
�[40m�[32minfo�[39m�[22m�[49m: Active Android device set to serial 'emulator-5554'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop ro.product.cpu.abi'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop ro.build.version.sdk'
�[40m�[32minfo�[39m�[22m�[49m: Waiting for device to be available (max 5 minutes)
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 wait-for-device'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop sys.boot_completed'
�[40m�[37mdbug�[39m�[22m�[49m: sys.boot_completed = '1'
�[40m�[37mdbug�[39m�[22m�[49m: Waited 0 seconds for device boot completion
�[40m�[37mdbug�[39m�[22m�[49m: Working with emulator-5554 (API 30)
�[40m�[37mdbug�[39m�[22m�[49m: Check current adb install and/or package verification settings
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell settings get global verifier_verify_adb_installs'
�[40m�[37mdbug�[39m�[22m�[49m: verifier_verify_adb_installs = 0
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell settings get global package_verifier_enable'
�[40m�[37mdbug�[39m�[22m�[49m: package_verifier_enable =
�[40m�[1m�[33mwarn�[39m�[22m�[49m: Installing debug apks on a device might be rejected with INSTALL_FAILED_VERIFICATION_FAILURE. Make sure to set 'package_verifier_enable' to '0'
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.core.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.core.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Waiting for command timed out: execution may be compromised
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: -2
Std out:
�[40m�[32minfo�[39m�[22m�[49m: Attempting to install /home/vsts/work/1/s/artifacts/bin/Core.DeviceTests/Release/net10.0-android/com.microsoft.maui.core.devicetests-Signed.apk
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 install /home/vsts/work/1/s/artifacts/bin/Core.DeviceTests/Release/net10.0-android/com.microsoft.maui.core.devicetests-Signed.apk'
�[40m�[1m�[33mwarn�[39m�[22m�[49m: Hit broken pipe error; Will make one attempt to restart ADB server, then retry the install
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 kill-server'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 start-server'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 install /home/vsts/work/1/s/artifacts/bin/Core.DeviceTests/Release/net10.0-android/com.microsoft.maui.core.devicetests-Signed.apk'
�[41m�[30mfail�[39m�[22m�[49m: Error:
Exit code: 255
Std out:
Performing Push Install
adb: error: failed to get feature set: device offline
�[41m�[1m�[37mcrit�[39m�[22m�[49m: Install failure: Test command cannot continue
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.core.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.core.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: 20
Std out:
Std err:
- waiting for device -
cmd: Can't find service: package
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.core.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.core.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: 20
Std out:
Std err:
cmd: Can't find service: package
XHarness exit code: 78 (PACKAGE_INSTALLATION_FAILURE)
Tests completed with exit code: 78
📁 Fix files reverted (2 files)
eng/pipelines/ci-copilot.ymlsrc/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
UI Tests
Full UI test matrix will run (no specific categories detected from PR changes).
Pre-Flight — Context & Validation
Issue: #35780 - Android RadialGradientBrush crashes when drawn with zero-size bounds
PR: #35781 - Fix Android RadialGradientBrush zero-size crash
Platforms Affected: Android
Files Changed: 1 implementation, 1 test
Key Findings
- Android
PlatformDrawableStyle.getShader()can constructandroid.graphics.RadialGradientwith radius0when a radial brush is drawn into zero-size bounds; Android throwsIllegalArgumentException: radius must be > 0. - PR fix adds an early zero-size guard in
PlatformDrawableStyle.getShader()and addsGraphicsTests.RadialGradientWithZeroSizeDoesNotThrowas an Android device test. - Gate was already completed separately and passed: the new Graphics device test fails without the fix and passes with the PR fix.
Code Review Summary
Verdict: NEEDS_DISCUSSION
Confidence: high
Errors: 0 | Warnings: 2 | Suggestions: 0
Key code review findings:
⚠️ PR includes unrelated CI/workflow changes not covered by the Android-focused narrative in the code-review agent's broader diff view.⚠️ Required CI was reported failing for head232eafc52f9e; existing bot analysis classified observed test failures as likely unrelated.- Android code-level finding: no ❌ correctness issues were found; the expert reviewer returned no inline findings for the Android fix.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35781 | Return null from getShader() when both drawable dimensions are zero before constructing any gradient shader. |
✅ PASSED (Gate) | src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java, src/Core/tests/DeviceTests/Graphics/GraphicsTests.Android.cs |
Original PR fix |
Code Review — Deep Analysis
Code Review — PR #35781
Independent Assessment
What this changes: The diff contains two groups of changes: (1) Android graphics now avoids creating a gradient Shader when both drawable dimensions are zero, with an Android device test for zero-size radial-gradient drawing; (2) CI/review-queue infrastructure changes that suppress PR-author mentions, guard the review-queue workflow to dotnet, force ci-copilot to rely on its inline Android AVD creation, and set __PWSH_LOGIN_CHECKED globally for pwsh startup stability.
Inferred motivation: The Android guard appears intended to prevent RadialGradient construction with radius 0. The workflow/pipeline changes appear intended to reduce unwanted notifications and stabilize CI/reviewer-agent Android/macOS execution.
Reconciliation with PR Narrative
Author claims: The PR title/body describe only an Android RadialGradientBrush crash fix for zero-size controls, including restoring the old zero-size guard semantics and adding validation for Android.
Agreement/disagreement: The Android code and test match the stated root cause and use the intended width == 0 && height == 0 guard. However, the PR currently also includes several unrelated CI/workflow commits (#35714, #35751, #35724) that are not described by the PR narrative. Existing automated test-failure review comments classify current failures as likely unrelated.
Findings
⚠️ Warning — PR includes unrelated CI/workflow changes not covered by the Android-focused narrative
The diff includes modified lines in .github/skills/find-reviewable-pr/scripts/query-reviewable-prs.ps1, .github/workflows/pr-review-queue.yml, eng/pipelines/ci-copilot.yml, and eng/pipelines/common/variables.yml, while the PR description only discusses the Android radial-gradient crash. These changes appear individually reasonable, but they materially change workflow/pipeline behavior and should be explicitly confirmed as intentional for this PR or split/rebased so reviewers are not approving unrelated infrastructure changes under an Android bug-fix title.
⚠️ Warning — Required CI is currently failing
GitHub check runs for head 232eafc52f9e show maui-pr, Build Analysis, Windows build/pack, and macOS build failures. Existing bot analysis says the observed test failures are likely unrelated, and I did not find code-level evidence that the added Android guard/test caused them. Per the skill rules, this should still block a clean LGTM until required CI is green or a maintainer accepts the failures as unrelated.
No ❌ error-level code correctness findings were found. The expert reviewer returned no inline findings.
Devil's Advocate
The Android guard returns null without clearing the cached shader, but applyStyle() immediately applies that null to the paint for zero-size draws; retaining the prior cached shader for a later return to the same non-zero dimensions is safe. The && zero-size condition matches the stated old behavior and avoids over-suppressing valid one-dimensional gradient cases. The workflow guards and PowerShell workaround are plausible, but because those files are security/CI-sensitive and outside the stated Android fix, human confirmation of PR scope is the main remaining concern.
Verdict: NEEDS_DISCUSSION
Confidence: high
Summary: The Android fix itself looks sound and covered by an appropriate Android device test. I would not give a clean LGTM yet because the PR includes unrelated CI/workflow changes not described by the narrative and required CI checks are failing, even if the failures appear unrelated.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | maui-expert-reviewer | Normalize zero drawable dimensions to a minimum positive shader extent before constructing gradient shaders. | ✅ PASS | 1 file | Passed Android Graphics device tests, but not selected because it creates shaders for invisible bounds and changes one-zero-dimension geometry. |
| 2 | maui-expert-reviewer | Guard the computed Android radial-gradient radius and return null only when radius <= 0. |
✅ PASS | 1 file | Selected: guards the actual Android constructor invariant, preserves positive-radius geometry, and covers degenerate radius inputs beyond only 0x0 dimensions. |
| PR | PR #35781 | Return null from getShader() when width == 0 && height == 0. |
✅ PASSED (Gate) | 2 files | Original PR fix; correct for the reported repro but less directly tied to the failing Android API precondition. |
Expert Review Loop
| Round | Candidate | Expert guidance | Test result | Learned |
|---|---|---|---|---|
| 1 | try-fix-1 | Normalize shader dimensions to keep shader creation behavior while avoiding zero-radius Android geometry. | ✅ PASS | Passing, but semantically broader than needed: invisible 0x0 drawables still allocate shaders and 0xN/Nx0 geometry changes to use a 1px extent. |
| 2 | try-fix-2 | Guard Android RadialGradient radius precondition directly, using the existing computed radius. |
✅ PASS | Cleaner and more robust: fixes the crash by enforcing radius > 0 exactly where Android requires it, without changing valid geometry. |
Candidate Details
try-fix-1
try-fix-1 — Normalize shader dimensions
Approach
Approach: Normalize shader dimensions
Normalize zero drawable dimensions to a minimum positive shader extent before constructing Android LinearGradient or RadialGradient.
Different from existing fix: The PR skips shader creation only for width == 0 && height == 0. This approach keeps shader creation behavior and instead avoids degenerate Android shader geometry by using at least one pixel for shader coordinate/radius calculations.
Diff
diff --git a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
index 7e0d03d7ba..f6ba9293ec 100644
--- a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
+++ b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
@@ -67,10 +67,13 @@ public class PlatformDrawableStyle {
}
if (this.shader == null) {
+ float shaderWidth = Math.max(1, width);
+ float shaderHeight = Math.max(1, height);
+
if (this.paintType == PlatformPaintType.LINEAR) {
this.shader = new LinearGradient(
- this.gradientBounds[0] * width, this.gradientBounds[1] * height, // Start point
- this.gradientBounds[2] * width, this.gradientBounds[3] * height, // End point
+ this.gradientBounds[0] * shaderWidth, this.gradientBounds[1] * shaderHeight, // Start point
+ this.gradientBounds[2] * shaderWidth, this.gradientBounds[3] * shaderHeight, // End point
this.gradientColors,
this.gradientPositions,
Shader.TileMode.CLAMP
@@ -78,8 +81,8 @@ public class PlatformDrawableStyle {
}
else if (this.paintType == PlatformPaintType.RADIAL) {
this.shader = new RadialGradient(
- this.gradientBounds[0] * width, this.gradientBounds[1] * height, // Center point
- this.gradientBounds[2] * Math.max(width, height), // Radius
+ this.gradientBounds[0] * shaderWidth, this.gradientBounds[1] * shaderHeight, // Center point
+ this.gradientBounds[2] * Math.max(shaderWidth, shaderHeight), // Radius
this.gradientColors,
this.gradientPositions,
Shader.TileMode.CLAMPTest Results
Result: Pass
Command: pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Core -Platform android -TestFilter "Category=Graphics" -Timeout "00:45:00"
Key output:
�[40m�[32minfo�[39m�[22m�[49m: Successfully installed /home/vsts/work/1/s/artifacts/bin/Core.DeviceTests/Release/net10.0-android/com.microsoft.maui.core.devicetests-Signed.apk
INSTRUMENTATION_RESULT: test-execution-summary=Tests run: 49 Passed: 49 Inconclusive: 0 Failed: 0 Ignored: 0
Tests run: 49 Passed: 49 Inconclusive: 0 Failed: 0 Ignored: 0
06-10 19:56:07.406 6065 6093 I DOTNET : [PASS] RadialGradientWithZeroSizeDoesNotThrow
06-10 19:56:07.456 6065 6093 I DOTNET : Tests run: 1320 Passed: 49 Inconclusive: 0 Failed: 0 Ignored: 1271
�[40m�[32minfo�[39m�[22m�[49m: Successfully uninstalled com.microsoft.maui.core.devicetests
XHarness exit code: 0
Failure Analysis
Not failed. However, this candidate is not demonstrably better than the PR fix because it creates gradient shaders for invisible zero-size drawables and changes geometry for one-zero-dimension cases by substituting a 1px extent.
try-fix-2
try-fix-2 — Guard RadialGradient constructor radius
Approach
Approach: Guard RadialGradient constructor radius
Compute the radial shader radius exactly as existing code does, then return null only when that radius violates Android's RadialGradient constructor precondition (radius > 0).
Different from existing fix: The PR checks the drawable dimension pair (width == 0 && height == 0) before all gradient creation. This approach guards the actual failing Android radial-gradient invariant and leaves valid positive-radius geometry unchanged.
Diff
diff --git a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
index 7e0d03d7ba..d24aada1a4 100644
--- a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
+++ b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformDrawableStyle.java
@@ -77,9 +77,14 @@ public class PlatformDrawableStyle {
);
}
else if (this.paintType == PlatformPaintType.RADIAL) {
+ float radius = this.gradientBounds[2] * Math.max(width, height);
+ if (radius <= 0) {
+ return null;
+ }
+
this.shader = new RadialGradient(
this.gradientBounds[0] * width, this.gradientBounds[1] * height, // Center point
- this.gradientBounds[2] * Math.max(width, height), // Radius
+ radius, // Radius
this.gradientColors,
this.gradientPositions,
Shader.TileMode.CLAMPTest Results
Result: Pass
Command: pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Core -Platform android -TestFilter "Category=Graphics" -Timeout "00:45:00"
Key output:
INSTRUMENTATION_RESULT: test-execution-summary=Tests run: 49 Passed: 49 Inconclusive: 0 Failed: 0 Ignored: 0
Tests run: 49 Passed: 49 Inconclusive: 0 Failed: 0 Ignored: 0
06-10 20:03:00.318 6525 6553 I DOTNET : [PASS] RadialGradientWithZeroSizeDoesNotThrow
06-10 20:03:00.362 6525 6553 I DOTNET : Tests run: 1320 Passed: 49 Inconclusive: 0 Failed: 0 Ignored: 1271
XHarness exit code: 0
Tests completed successfully
Failure Analysis
Not failed. This candidate is demonstrably better than the PR fix because it guards the exact Android RadialGradient constructor invariant (radius > 0), preserves existing geometry for positive-radius gradients, and also covers degenerate radius inputs beyond only width == 0 && height == 0.
Regression / Gate Context
- Gate was already completed before this phase and passed: without fix failed, with PR fix passed. Gate was not re-run.
- Candidate validation command for both attempts:
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Core -Platform android -TestFilter "Category=Graphics" -Timeout "00:45:00". - Regression cross-reference status available in
regression-check/: CLEAN, no risks.
Exhausted: No — stopped because candidate #2 passed and is demonstrably better than the PR fix.
Selected Fix: Candidate #2 — Guard computed RadialGradient radius (radius <= 0) before calling Android RadialGradient, because it targets the exact platform API invariant while preserving existing positive-radius rendering semantics.
Report — Final Recommendation
Comparative Fix Report — PR #35781
Candidates compared
| Rank | Candidate | Regression status | Assessment |
|---|---|---|---|
| 1 | pr-plus-reviewer |
✅ PASS evidence from the raw PR gate plus try-fix-2's passing run for the same radius-guard implementation |
Best candidate. Keeps the PR's reproduced zero-size regression test and applies the expert reviewer's correction to guard Android's actual RadialGradient invariant (radius > 0). |
| 2 | try-fix-2 |
✅ PASS | Strong implementation-only candidate. It guards the computed radial radius before calling RadialGradient, preserves valid positive-radius geometry, and covers degenerate radius inputs beyond 0x0 bounds. Ranked below pr-plus-reviewer because it does not include the PR's test improvements as part of the candidate patch. |
| 3 | pr |
✅ PASS (gate) | Fixes the reported zero-size crash and includes a good Android device regression test, but it only checks width == 0 && height == 0. Expert review found this misses other zero-radius radial gradients that can still throw. |
| 4 | try-fix-1 |
✅ PASS | Avoids the crash by normalizing zero dimensions to at least 1px before shader construction. This is broader than needed, creates shaders for invisible 0x0 bounds, and changes one-zero-dimension gradient geometry. |
No candidate with a failed regression test was ranked above a passing candidate; all recorded STEP 5a candidates passed their Android Graphics regression run.
Winning candidate
Winner: pr-plus-reviewer
The winning approach is to keep the PR's regression coverage and apply the expert reviewer's targeted radial-radius guard. This directly enforces the Android platform API precondition, avoids the raw PR's incomplete 0x0-only guard, and avoids the semantic geometry changes introduced by try-fix-1.
Decision rationale
try-fix-2 independently demonstrated that the computed-radius guard passes the Android Graphics regression suite, and the expert reviewer independently identified the same radius precondition gap in the raw PR. pr-plus-reviewer combines that better implementation with the PR's existing regression-test contribution, so it is the most complete and least behavior-changing fix.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------
… size (#35781) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - If a RadialGradientBrush is applied to a zero-size control on Android, the app faults with **Java.Lang.IllegalArgumentException: 'ending radius must be > 0'** ### Root Cause - PR #31567 refactored gradient shader creation into the new PlatformDrawableStyle.java but missed porting the zero-size guard (if (_width == 0 && _height == 0) return;) that existed in the old MauiDrawable.Android.cs — specifically in SetLinearGradientPaint and SetRadialGradientPaint. Without this guard, getShader() is called during initial layout when width = 0 and height = 0, producing radius = 0 and causing IllegalArgumentException: radius must be > 0 from Android's RadialGradient constructor. ### Description of Change - In PlatformDrawableStyle.getShader(), added an early return of null when width == 0 && height == 0, preventing LinearGradient/RadialGradient from being constructed with zero dimensions. ### Issues Fixed Fixes #35753 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <video src="https://github.com/user-attachments/assets/58d6cdd5-1cbf-4125-b248-eb312daeb7e3"> | <video src="https://github.com/user-attachments/assets/a136e3b7-35f9-48dc-aca5-36c215d32c1a"> | ---------


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!
Issue Details
Root Cause
Description of Change
Issues Fixed
Fixes #35753
Validated the behaviour in the following platforms
Output
Before.mov
After.mov