[Regression][Windows]Fix Exception thrown on .NET 10 Windows when calling Permissions.CheckStatusAsync<Permissions.Microphone>()#33179
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a Windows-specific exception that occurs when calling Permissions.CheckStatusAsync<Permissions.Microphone>() on .NET 10 unpackaged apps. The issue was caused by the permission logic always validating against AppxManifest.xml, which doesn't exist in unpackaged apps (now the default for Windows). The fix adds conditional checks using AppInfoUtils.IsPackagedApp to skip manifest validation for unpackaged apps.
Key Changes:
- Modified microphone permission logic to skip
EnsureDeclared()for unpackaged apps - Refactored
RequestAsyncmethod to extract permission request logic intoTryRequestPermissionAsync - Added UI test for Windows to verify the fix
- Added new "Essentials" category to UI test infrastructure
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/Essentials/src/Permissions/Permissions.windows.cs | Adds conditional IsPackagedApp checks before calling EnsureDeclared() in both CheckStatusAsync and RequestAsync methods, and extracts try-catch logic into a new TryRequestPermissionAsync method |
| src/Controls/tests/TestCases.Shared.Tests/UITestCategories.cs | Adds new "Essentials" category constant for UI test categorization |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32989.cs | NUnit test implementation that taps a button and verifies no crash occurs |
| src/Controls/tests/TestCases.HostApp/Issues/Issue32989.cs | Test page with button to trigger microphone permission check |
| eng/pipelines/common/ui-tests.yml | Adds "Essentials" to the test category groups in the pipeline configuration |
jfversluis
left a comment
There was a problem hiding this comment.
Can we do this with a device tests rather than with a UI test? I think all of the Essentials are device tests?
@jfversluis , This issue reproduces only in unpackaged apps, not in packaged apps. Since only the HostApp is an unpackaged app and the DeviceTest is packaged, I wrote a UI test. |
## Description Remove the "Are you waiting for the changes in this PR to be merged?" note from all Copilot instruction files. This note was previously required at the top of every PR description so users could find instructions on how to test PR artifacts. We now have a **dogfooding comment bot** that automatically posts testing instructions under each PR, making this manual note redundant. Copilot agents were still prepending this note to every PR description because it was hardcoded in: - `.github/copilot-instructions.md` (main instructions) - `.github/skills/pr-finalize/SKILL.md` (PR finalization skill) - `.github/skills/pr-finalize/references/complete-example.md` (example PR) ### Issues Fixed N/A — instruction cleanup only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Problem The `maui-pr-uitests` pipeline has 98+ test jobs that all publish artifacts using `PublishBuildArtifacts@1` with **no artifact name**, defaulting to `drop`. When multiple jobs upload the same file to the same container simultaneously, AzDO blob storage encounters write conflicts: ``` Blob is incomplete (missing block). Blob: 29adda685a1ff1119a49000d3a9183a5, Expected Offset: 0, Actual Offset: 8388608 ##[error]File upload failed even after retry. ``` ### Recent failures - [Build 1334980](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1334980): 3 jobs failed (Controls CollectionView, Controls (vlatest), Controls (vlatest) CollectionView) - [Build 1334245](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1334245): 1 job failed (Controls (vlatest)) The specific collision: both "Controls (vlatest)" and "Controls (vlatest) CollectionView" upload `drop/logs/appium_ios_Controls.TestCases.iOS.Tests-Release-ios-CollectionView.log` — same blob ID, concurrent writes. ## Fix Add a unique artifact name per job using `$(System.StageName)-$(System.JobName)-$(System.JobAttempt)` in `eng/pipelines/common/ui-tests-steps.yml`. This matches the pattern already used by snapshot diff artifacts in `ui-tests-collect-snapshot-diffs.yml`. Fixes dotnet#34477 Ref: dotnet/dnceng#1916 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 -- 33179Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 33179" |
|
/azp run maui-pr-devicetests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…ling Permissions.CheckStatusAsync<Permissions.Microphone>() (#33179) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On .NET 10 Windows, calling Permissions.CheckStatusAsync<Permissions.Microphone>() throws an exception when the app is running as an unpackaged app. This is a regression introduced after Windows apps were changed to run as unpackaged by default. In unpackaged apps, AppxManifest.xml is not used, so microphone capabilities declared in the manifest are ignored. However, the current implementation always validates microphone capability declarations against AppxManifest.xml, which causes an exception for unpackaged apps. ### Description of Change <!-- Enter description of the fix in this section --> Updated the Windows microphone permission logic to skip manifest capability checks for unpackaged apps. The microphone declaration is now required only for packaged apps, preventing exceptions and aligning the behavior with other Essentials APIs. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32989 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [x] Windows - [ ] iOS - [ ] Mac | Before | After | |---------|--------| | **Windows**<br> <img src="https://github.com/user-attachments/assets/7870d1a7-eeab-4e85-be4d-b951f0bd3d19" width="600" height="300"> | **Windows**<br> <img src="https://github.com/user-attachments/assets/bd43f5b8-85b7-4e3c-8404-d01c165fefa4" width="600" height="300"> | ---------
…ling Permissions.CheckStatusAsync<Permissions.Microphone>() (dotnet#33179) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On .NET 10 Windows, calling Permissions.CheckStatusAsync<Permissions.Microphone>() throws an exception when the app is running as an unpackaged app. This is a regression introduced after Windows apps were changed to run as unpackaged by default. In unpackaged apps, AppxManifest.xml is not used, so microphone capabilities declared in the manifest are ignored. However, the current implementation always validates microphone capability declarations against AppxManifest.xml, which causes an exception for unpackaged apps. ### Description of Change <!-- Enter description of the fix in this section --> Updated the Windows microphone permission logic to skip manifest capability checks for unpackaged apps. The microphone declaration is now required only for packaged apps, preventing exceptions and aligning the behavior with other Essentials APIs. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes dotnet#32989 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [x] Windows - [ ] iOS - [ ] Mac | Before | After | |---------|--------| | **Windows**<br> <img src="https://github.com/user-attachments/assets/7870d1a7-eeab-4e85-be4d-b951f0bd3d19" width="600" height="300"> | **Windows**<br> <img src="https://github.com/user-attachments/assets/bd43f5b8-85b7-4e3c-8404-d01c165fefa4" width="600" height="300"> | ---------
…ling Permissions.CheckStatusAsync<Permissions.Microphone>() (#33179) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On .NET 10 Windows, calling Permissions.CheckStatusAsync<Permissions.Microphone>() throws an exception when the app is running as an unpackaged app. This is a regression introduced after Windows apps were changed to run as unpackaged by default. In unpackaged apps, AppxManifest.xml is not used, so microphone capabilities declared in the manifest are ignored. However, the current implementation always validates microphone capability declarations against AppxManifest.xml, which causes an exception for unpackaged apps. ### Description of Change <!-- Enter description of the fix in this section --> Updated the Windows microphone permission logic to skip manifest capability checks for unpackaged apps. The microphone declaration is now required only for packaged apps, preventing exceptions and aligning the behavior with other Essentials APIs. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32989 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [x] Windows - [ ] iOS - [ ] Mac | Before | After | |---------|--------| | **Windows**<br> <img src="https://github.com/user-attachments/assets/7870d1a7-eeab-4e85-be4d-b951f0bd3d19" width="600" height="300"> | **Windows**<br> <img src="https://github.com/user-attachments/assets/bd43f5b8-85b7-4e3c-8404-d01c165fefa4" width="600" height="300"> | ---------
Issue Details
On .NET 10 Windows, calling
Permissions.CheckStatusAsync<Permissions.Microphone>() throws an exception when the app is running as an unpackaged app.
This is a regression introduced after Windows apps were changed to run as unpackaged by default. In unpackaged apps, AppxManifest.xml is not used, so microphone capabilities declared in the manifest are ignored. However, the current implementation always validates microphone capability declarations against AppxManifest.xml, which causes an exception for unpackaged apps.
Description of Change
Updated the Windows microphone permission logic to skip manifest capability checks for unpackaged apps. The microphone declaration is now required only for packaged apps, preventing exceptions and aligning the behavior with other Essentials APIs.
Issues Fixed
Fixes #32989
Tested the behavior in the following platforms.