From a8fb53e92ae31eced207c56d4d2662467afa7d9e Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Thu, 15 May 2025 22:28:23 -0400 Subject: [PATCH] Limit use of deprecated Android display API (#18722) * update androidx version * limit deprecated android display api to below api 30 --- .../Avalonia.Android/Avalonia.Android.csproj | 3 +- .../Platform/AndroidScreens.cs | 40 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj index 170cc088fb..2fb849ee0d 100644 --- a/src/Android/Avalonia.Android/Avalonia.Android.csproj +++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj @@ -7,7 +7,8 @@ - + + diff --git a/src/Android/Avalonia.Android/Platform/AndroidScreens.cs b/src/Android/Avalonia.Android/Platform/AndroidScreens.cs index 667ec260fa..95d2530edc 100644 --- a/src/Android/Avalonia.Android/Platform/AndroidScreens.cs +++ b/src/Android/Avalonia.Android/Platform/AndroidScreens.cs @@ -5,6 +5,8 @@ using Android.Hardware.Display; using Android.Runtime; using Android.Util; using Android.Views; +using AndroidX.Core.View; +using AndroidX.Window.Layout; using Avalonia.Android.Platform.SkiaPlatform; using Avalonia.Platform; using AndroidOrientation = global::Android.Content.Res.Orientation; @@ -19,16 +21,29 @@ internal class AndroidScreen(Display display) : PlatformScreen(new PlatformHandl var naturalOrientation = ScreenOrientation.Portrait; var rotation = display.Rotation; + IsPrimary = display.DisplayId == Display.DefaultDisplay; - if (OperatingSystem.IsAndroidVersionAtLeast(30) - && display.DisplayId == context.Display?.DisplayId - && context.Resources?.DisplayMetrics is { } primaryMetrics) + if (OperatingSystem.IsAndroidVersionAtLeast(30)) { - IsPrimary = true; - Scaling = primaryMetrics.Density; - Bounds = WorkingArea = new(0, 0, primaryMetrics.WidthPixels, primaryMetrics.HeightPixels); - - var orientation = context.Resources.Configuration?.Orientation; + var metricsCalc = WindowMetricsCalculator.Companion.OrCreate; + // a display context is guaranteed to be created for a display on API 30 and above, but we fallback to the app context if OEM messes up + var displayContext = context.CreateDisplayContext(display) ?? context; + // Get the bounds of the display + var metrics = metricsCalc.ComputeMaximumWindowMetrics(displayContext); + Bounds = new(metrics.Bounds.Left, metrics.Bounds.Top, metrics.Bounds.Width(), metrics.Bounds.Height()); + + var inset = metrics.WindowInsets.GetInsets(WindowInsetsCompat.Type.SystemBars()); + WorkingArea = new(Bounds.X + inset.Left, + Bounds.Y + inset.Top, + Bounds.Width - (inset.Left + inset.Right), + Bounds.Height - (inset.Top + inset.Bottom)); + + if (context.Resources?.Configuration is { } config) + { + Scaling = config.DensityDpi / (float)global::Android.Util.DisplayMetricsDensity.Default; + } + + var orientation = displayContext.Resources?.Configuration?.Orientation; if (orientation == AndroidOrientation.Square) naturalOrientation = ScreenOrientation.None; else if (rotation is SurfaceOrientation.Rotation0 or SurfaceOrientation.Rotation180) @@ -42,17 +57,8 @@ internal class AndroidScreen(Display display) : PlatformScreen(new PlatformHandl } else { - IsPrimary = false; - // These Display methods are deprecated since 31 SDK, - // But Android doesn't have any replacement, except for the primary screen. -#pragma warning disable CS0618 // Type or member is obsolete -#pragma warning disable CA1422 // Validate platform compatibility -#pragma warning disable CA1416 // Validate platform compatibility var displayMetrics = new DisplayMetrics(); display.GetRealMetrics(displayMetrics); -#pragma warning restore CA1416 // Validate platform compatibility -#pragma warning restore CA1422 // Validate platform compatibility -#pragma warning restore CS0618 // Type or member is obsolete Scaling = displayMetrics.Density; Bounds = WorkingArea = new(0, 0, displayMetrics.WidthPixels, displayMetrics.HeightPixels); }