Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 26, 2025

  • Understand the problem: OnBackPressed is deprecated on Android and no longer triggered on Android 36+
  • Explore existing code:
    • ApplicationActivity.Android.cs and ApplicationActivity.cs (Skia Android) both override OnBackPressed
    • SystemNavigationManager.cs provides RequestBack() method and BackRequested event
    • Both BaseActivity classes extend AndroidX.AppCompat.App.AppCompatActivity which inherits from ComponentActivity
  • Implement OnBackPressedCallback support:
    • Create a custom OnBackPressedCallback that invokes SystemNavigationManager.RequestBack()
    • Register the callback with OnBackPressedDispatcher in ApplicationActivity
    • Enable/disable the callback based on whether back handling should be active
    • Keep backward compatibility by maintaining OnBackPressed for older Android versions
  • Update both ApplicationActivity.Android.cs (native) and ApplicationActivity.cs (Skia)
  • Extract shared helper class to eliminate code duplication
  • Build and validate changes
  • Run code review

Fixes https://github.com/unoplatform/uno/issues/#11748

Original prompt

This section details on the original issue you should resolve

<issue_title>Add built-in support for OnBackPressedCallback on Android</issue_title>
<issue_description>

What would you like to be added:

Currently we use the OnBackPressed handler on Android, which is now deprecated. Instead OnBackPressedCallback should be used, which however has a different handling approach - when it is registered, you are required to handle the back press (so there is no way to decide whether the back press will be handled when it is already being executed). We will probably need some new API for this to let user register/unregister the callback on demand - and something which will also work as a replacement of SystemNavigationManager on other targets (e.g. WinAppSDK, where SystemNavigationManager does not exist).

It seems the Application Activity's DispatchKeyEvent for the back button is triggered before the callback, which could be an opportunity to trigger the SystemNavigationManager and handle it there, but it is not going to be able to handle the back gesture probably.

Why is this needed:

For which Platform:

  • WebAssembly
  • Android
  • iOS
  • macOS (AppKit)
  • Mac Catalyst
  • Skia
    • WPF
    • GTK (Linux)
    • Linux Framebuffer
    • Tizen
  • Windows
  • Build tasks
  • Solution Templates

Anything else we need to know?

</issue_description>

Comments on the Issue (you are @copilot in this section)

@MartinZikmund This is now very urgent, as Android 36 devices now do not trigger `OnBackPressed` at all, meaning all current Uno apps using `SystemNavigationManager` will always close on back button press/gesture.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@MartinZikmund
Copy link
Member

@copilot continue the implementation

This implements the new OnBackPressedCallback mechanism required for
Android 33+ where OnBackPressed is deprecated and Android 36+ where
OnBackPressed is no longer called at all.

The implementation:
- Creates a custom SystemNavigationManagerBackPressedCallback that
  integrates with the existing SystemNavigationManager.BackRequested event
- Registers the callback with OnBackPressedDispatcher in OnCreate()
- If the back press is not handled by the app (RequestBack returns false),
  temporarily disables the callback and re-invokes the dispatcher to allow
  the default system behavior

This ensures that Uno apps continue to work correctly with the hardware
back button and predictive back gesture on all Android versions.

Fixes https://github.com/unoplatform/uno/issues/#11748

Co-authored-by: MartinZikmund <[email protected]>
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Address code review feedback by extracting SystemNavigationManagerBackPressedCallback
into a shared helper class in Uno.UI.Helpers namespace. The class is shared between
both the native Android and Skia Android implementations via:
- Direct inclusion in Uno.UI.netcoremobile.csproj
- Linked file in Uno.UI.Runtime.Skia.Android.csproj

This eliminates code duplication and makes maintenance easier.

Co-authored-by: MartinZikmund <[email protected]>
Copy link
Contributor Author

Copilot AI commented Nov 27, 2025

@copilot continue the implementation

Implemented OnBackPressedCallback support for Android 33+ in commit 146562e.

The implementation:

  • Creates a SystemNavigationManagerBackPressedCallback class that registers with OnBackPressedDispatcher in OnCreate()
  • The callback invokes SystemNavigationManager.RequestBack() when back is pressed
  • If not handled, temporarily disables itself and re-invokes the dispatcher to allow default system behavior
  • Updates both native Android (ApplicationActivity.Android.cs) and Skia Android (ApplicationActivity.cs)
  • Extracted the shared callback to Uno.UI.Helpers.BackPressedCallbackHelper.Android.cs to eliminate code duplication

This ensures that Uno apps continue to work correctly with the hardware back button and predictive back gesture on all Android versions, including Android 36+ where OnBackPressed is no longer called at all.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • aka.ms
    • Triggering command: /usr/bin/curl curl -I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 REDACTED (dns block)
  • crl.godaddy.com
    • Triggering command: /home/REDACTED/.dotnet/dotnet dotnet restore Uno.UI-netcoremobile-only.slnf (dns block)
  • ocsp.godaddy.com
    • Triggering command: /home/REDACTED/.dotnet/dotnet dotnet restore Uno.UI-netcoremobile-only.slnf (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of MartinZikmund November 27, 2025 13:34
@unodevops
Copy link
Contributor

🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-21969/docs/index.html

@unodevops
Copy link
Contributor

🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21969/wasm-skia-net9/index.html

@nventive-devops
Copy link
Contributor

The build 185388 found UI Test snapshots differences: android-28-net9: 16, android-28-net9-Snap: 41, ios: 4, ios-Snap: 52, skia-linux-screenshots: 76, skia-windows-screenshots: 443, wasm: 114, wasm-automated-net10.0-WinUI-Benchmarks-automated: 0, wasm-automated-net10.0-WinUI-Default-automated: 12, wasm-automated-net10.0-WinUI-RuntimeTests-0: 0, wasm-automated-net10.0-WinUI-RuntimeTests-1: 0, wasm-automated-net10.0-WinUI-RuntimeTests-2: 0

Details
  • android-28-net9: 16 changed over 825

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • Detereminate_ProgressRing_Validation25_[#FF0000_#008000_#FF0000_#FF0000]_Progress-Ring-Value-25
    • Detereminate_ProgressRing_Validation50_[#FF0000_#008000_#008000_#FF0000]_Progress-Ring-Value-50
    • NativeCommandBar_Size_Uno_UI_Samples_Content_UITests_CommandBar_CommandBar_Dynamic
    • When_NoSelectionWithItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers
    • When_NoSelection_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers
    • When_Parent_PointerMoved_After_drag_on_non-scrolling_ScrollViewer
    • When_Parent_PointerMoved_After_drag_on_ScrollViewer_-_touch
    • ProgressRing_IsEnabled_Running_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220
    • ProgressRing_Visibility_Collapsed_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220
    • When_ExtendedSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers
    • WebView_NavigateToAnchor_Initial
    • DecimalFormatterTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage
    • When_SingleSelectionWithItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers
    • ListView_ListViewWithHeader_InitializesTest_SamplesApp_Windows_UI_Xaml_Controls_ListView_HorizontalListViewGrouped
    • Detereminate_ProgressRing_Validation75_[#FF0000_#008000_#008000_#008000]_Progress-Ring-Value-75
    • UpDownEnabledTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage
  • android-28-net9-Snap: 41 changed over 1077

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • Gesture_Recognizer_Pointer_Events_test_bench_UITests_Shared_Windows_UI_Input_GestureRecognizer_PointersEvents
    • SwipeControl_MUXControlsTestApp_SwipeControlPage2_MUXControlsTestApp_SwipeControlPage2
    • ListView_ListView_With_ListViews_Count_Measure_UITests_Shared_Windows_UI_Xaml_Controls_ListView_ListView_With_ListViews_Count_Measure
    • Scrolling_MUXControlsTestApp_ScrollViewWithScrollControllersPage_MUXControlsTestApp_ScrollViewWithScrollControllersPage
    • ListView_ListViewChangeView_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewChangeView
    • Default_SamplesApp_Wasm_Windows_UI_Xaml_Controls_ListView_ListView_IsSelected_SamplesApp_Wasm_Windows_UI_Xaml_Controls_ListView_ListView_IsSelected
    • Default_Uno_UI_Samples_Content_UITests_WebView_WebView_AnchorNavigation_Uno_UI_Samples_Content_UITests_WebView_WebView_AnchorNavigation
    • Icons_UITests_Microsoft_UI_Xaml_Controls_ImageIconTests_ImageIconPage_UITests_Microsoft_UI_Xaml_Controls_ImageIconTests_ImageIconPage
    • Icons_UITests_Shared_Windows_UI_Xaml_Controls_BitmapIconTests_BitmapIcon_Foreground_UITests_Shared_Windows_UI_Xaml_Controls_BitmapIconTests_BitmapIcon_Foreground
    • MUX_NumberBox_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage
    • CommandBar_Examples_Uno_UI_Samples_Content_UITests_CommandBar_CommandBar_Examples
    • NavigationView_MUXControlsTestApp_NavigationViewRS4Page_MUXControlsTestApp_NavigationViewRS4Page
    • Image_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal
    • ListView_ListViewResizable_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewResizable
    • Scrolling_MUXControlsTestApp_ScrollViewDynamicPage_MUXControlsTestApp_ScrollViewDynamicPage
    • Scrolling_MUXControlsTestApp_ScrollViewKeyboardAndGamepadNavigationPage_MUXControlsTestApp_ScrollViewKeyboardAndGamepadNavigationPage
    • GridView_Uno_UI_Samples_Content_UITests_GridView_GridViewScrollIntoViewTest_Uno_UI_Samples_Content_UITests_GridView_GridViewScrollIntoViewTest
    • ListView_ListView_KeyboardInterception_UITests_Windows_UI_Xaml_Controls_ListView_ListView_KeyboardInterception
    • NavigationView_MUXControlsTestApp_NavigationViewTopNavOnlyPage_MUXControlsTestApp_NavigationViewTopNavOnlyPage
    • NavigationView_MUXControlsTestApp_NavigationViewTopNavPage_MUXControlsTestApp_NavigationViewTopNavPage
  • ios: 4 changed over 255

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • Check_ListView_Swallows_Measure_UITests_Shared_Windows_UI_Xaml_Controls_ListView_ListView_With_ListViews_Count_Measure
    • ProgressRing_IsEnabled_Running_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220
    • ProgressRing_Visibility_Collapsed_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220
    • TextBox_UpdatedBinding_On_OneWay_Mode_UITests_Windows_UI_Xaml_Controls_TextBox_TextBox_Bindings
  • ios-Snap: 52 changed over 994

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • Grid_Grid_DataBound_ColumnRow_Definitions_Uno_UI_Samples_Content_UITests_GridTestsControl_Grid_DataBound_ColumnRow_Definitions
    • Brushes_ImageBrushStretch2_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushStretch2
    • Brushes_ImageBrushWithScaleTransform_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushWithScaleTransform
    • Brushes_Uno_UI_Samples_Samples_Shared_Content_UITests_ImageBrushInList_Uno_UI_Samples_Samples_Shared_Content_UITests_ImageBrushInList
    • Default_Uno_UI_Samples_Content_UITests_WebView_WebView_AnchorNavigation_Uno_UI_Samples_Content_UITests_WebView_WebView_AnchorNavigation
    • Default_SamplesApp_Wasm_Windows_UI_Xaml_Controls_ListView_ListView_IsSelected_SamplesApp_Wasm_Windows_UI_Xaml_Controls_ListView_ListView_IsSelected
    • Grid_CenteredGridinGridwiththreefixedsizechildren_Uno_UI_Samples_Content_UITests_GridTestsControl_CenteredGridinGridwiththreefixedsizechildren
    • Image_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal
    • Image_UITests_Windows_UI_Xaml_Controls_ImageTests_Image_Formats_UITests_Windows_UI_Xaml_Controls_ImageTests_Image_Formats
    • Image_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Taller_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Taller
    • Image_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Bigger_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Bigger
    • Image_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Wider_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Wider
    • Image_UITests_Windows_UI_Xaml_Controls_ImageTests_Image_Margin_Large_UITests_Windows_UI_Xaml_Controls_ImageTests_Image_Margin_Large
    • Microsoft_UI_Xaml_Media_UITests_Windows_UI_Xaml_Media_ThemeShadowTests_ThemeShadow_Overlap_UITests_Windows_UI_Xaml_Media_ThemeShadowTests_ThemeShadow_Overlap
    • Image_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Equal_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Equal
    • PagerControl_UITests_Microsoft_UI_Xaml_Controls_PagerControlTests_PagerControlPage_UITests_Microsoft_UI_Xaml_Controls_PagerControlTests_PagerControlPage
    • WebView_WebView2_NavigateToUri_SamplesApp_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigateToUri
    • Performance_UITests_Windows_UI_Xaml_Performance_Performance_1000ButtonsContinuousRendering_UITests_Windows_UI_Xaml_Performance_Performance_1000ButtonsContinuousRendering
    • Popup_MessageDialog_UITests_Shared_Windows_UI_Xaml_Controls_Popup_MessageDialog
    • ColorPicker_ColorPickerSample_UITests_Microsoft_UI_Xaml_Controls_ColorPickerTests_ColorPickerSample
  • skia-linux-screenshots: 76 changed over 2306

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • CalendarView_Theming.png
    • ClipboardTests.png-dark
    • ImageBrushInList.png-dark
    • ImageBrushInList.png
    • EllipsemaskingEllipseGrid.png-dark
    • EllipsemaskingEllipseGrid.png
    • ImageBrush_Stretch.png-dark
    • ImageBrush_Stretch.png
    • Buttons.png
    • CalendarView_Theming.png-dark
    • DoubleImageBrushInList.png-dark
    • DoubleImageBrushInList.png
    • Focus_FocusVisual_Properties.png-dark
    • Focus_FocusVisual_Properties.png
    • ImageBrush_Formats.png-dark
    • ImageBrush_Formats.png
    • ButtonClippingTestsControl.png
    • Buttons.png-dark
    • Gamepad_CurrentReading.png-dark
    • DropDownButtonPage.png-dark
  • skia-windows-screenshots: 443 changed over 2306

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • AppBarButtonWithIconTest.png-dark
    • Attributed_text_Simple.png-dark
    • Attributed_text_Simple.png
    • Border_With_RotateTransform.png
    • Border_With_ScaleTransform.png-dark
    • CenteredGridinGridwiththreefixedsizechildren.png-dark
    • Grid_DataBound_ColumnRow_Definitions.png-dark
    • Grid_DataBound_ColumnRow_Definitions.png
    • Grid_InsideStackPanel_InsideButton.png-dark
    • Grid_InsideStackPanel_InsideButton.png
    • AppBarButtonTest.png-dark
    • AppBarToggleButtonTest.png
    • Attributed_text_Supserscript.png-dark
    • CalendarView_Theming.png-dark
    • CalendarView_Theming.png
    • DisplayInformation.png-dark
    • DisplayInformation.png
    • Gamepad_CurrentReading.png-dark
    • Gamepad_CurrentReading.png
    • Gamepad_Enumeration.png-dark
  • wasm: 114 changed over 1058

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • MUXControlsTestApp.NavigationViewIsPaneOpenPage
    • SamplesApp.Samples.NavigationViewSample.NavigationViewSample
    • SamplesApp.Windows_UI_Xaml_Controls.ListView.ListView_Changing_Text
    • UITests.Shared.Microsoft_UI_Xaml_Controls.ExpanderTests.WinUIExpanderPage
    • UITests.Shared.Windows_UI_Xaml_Controls.ComboBox.ComboBox_ComboBoxItem_Selection
    • UITests.Shared.Windows_UI_Xaml_Controls.Slider.Slider_Features
    • UITests.Windows_UI_Xaml_Controls.ComboBox.ComboBox_Disabled
    • UITests.Windows_UI_Xaml_Controls.ImageTests.SvgImageSource_FromStream
    • UITests.Windows_UI_Xaml_Controls.TextBox.TextBox_CornerRadius
    • MUXControlsTestApp.NavigationViewCustomThemeResourcesPage
    • MUXControlsTestApp.ScrollViewPage
    • UITests.Shared.Windows_UI_Xaml_Controls.WebView.WebView_NavigateToString2
    • UITests.Windows_UI_Xaml_Controls.ListView.ListView_Selection_Events
    • UITests.Windows_UI_Xaml_Controls.TextBox.TextBox_Wrap
    • Uno.UI.Samples.Content.UITests.Flyout.Flyout_Simple
    • MUXControlsTestApp.NavigationViewMenuItemStretchPage
    • MUXControlsTestApp.NavigationViewStretchPage
    • MUXControlsTestApp.SelectorBarPage
    • UITests.Microsoft_UI_Xaml_Controls.CommandBarTests.CommandBar_Primary_And_Secondary
    • UITests.Shared.Windows_UI.Xaml_Automation.AutomationProperties_AutomationId
  • wasm-automated-net10.0-WinUI-Benchmarks-automated: 0 changed over 1

  • wasm-automated-net10.0-WinUI-Default-automated: 12 changed over 877

    🚨🚨 Comparison Details (first 20) 🚨🚨
    • Default_StrokeThickness_MyPolygon
    • Default_StrokeThickness_MyEllipse
    • Default_StrokeThickness_MyPolyline
    • TestProgressRing_InitialState_UITests_Microsoft_UI_Xaml_Controls_ProgressRing_WinUIProgressRing_Features
    • ListView_SelectedItems_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewSelectedItems
    • Default_StrokeThickness_MyRect
    • Default_StrokeThickness_MyLine
    • Default_StrokeThickness_MyPath
    • ToggleCollapsedStateToVerifyClipping_UITests_Shared_Microsoft_UI_Xaml_Controls_ExpanderTests_ExpanderColorValidationPage
    • SequentialAnimations_SamplesApp_Windows_UI_Xaml_Media_Animation_SequentialAnimationsPage
    • When_TransformToVisual_ScrollViewer_UITests_Shared_Windows_UI_Xaml_UIElementTests_TransformToVisual_ScrollViewer
    • When_Theme_Changed_No_Crash_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming
  • wasm-automated-net10.0-WinUI-RuntimeTests-0: 0 changed over 1

  • wasm-automated-net10.0-WinUI-RuntimeTests-1: 0 changed over 1

  • wasm-automated-net10.0-WinUI-RuntimeTests-2: 0 changed over 1

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add built-in support for OnBackPressedCallback on Android

5 participants