Skip to content

Commit

Permalink
fix(reg): Fix support of Android versions below 30 (including UI test…
Browse files Browse the repository at this point in the history
… failing on CI)
  • Loading branch information
dr1rrb committed Oct 6, 2021
1 parent 316aa6f commit 07c3d23
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 34 deletions.
18 changes: 18 additions & 0 deletions src/Uno.UI/UI/Xaml/FrameworkElement.EffectiveViewport.Interface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#nullable enable

using System;
using System.Linq;

namespace Windows.UI.Xaml
{
// Internal interface used to allow communication between the real FrameworkElement
// and presenters that are only implementing the IFrameworkElement interface (cf. FrameworkElementMixins.tt).
// It must not be used anywhere else out of the file.
internal interface IFrameworkElement_EffectiveViewport
{
void InitializeEffectiveViewport();
IDisposable RequestViewportUpdates(bool isInternal, IFrameworkElement_EffectiveViewport? child = null);
void OnParentViewportChanged(bool isInitial, bool isInternal, IFrameworkElement_EffectiveViewport parent, ViewportInfo viewport);
void OnLayoutUpdated();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,6 @@

namespace Windows.UI.Xaml
{
// Internal interface used to allow communication between the real FrameworkElement
// and presenters that are only implementing the IFrameworkElement interface (cf. FrameworkElementMixins.tt).
// It must not be used anywhere else out of the file.
internal interface IFrameworkElement_EffectiveViewport
{
void InitializeEffectiveViewport();
IDisposable RequestViewportUpdates(bool isInternal, IFrameworkElement_EffectiveViewport? child = null);
void OnParentViewportChanged(bool isInitial, bool isInternal, IFrameworkElement_EffectiveViewport parent, ViewportInfo viewport);
void OnLayoutUpdated();
}

internal struct ViewportInfo : IEquatable<ViewportInfo>
{
public static ViewportInfo Empty { get; } = new ViewportInfo { Effective = Rect.Empty, Clip = Rect.Empty };
Expand Down
58 changes: 35 additions & 23 deletions src/Uno.UI/UI/Xaml/Window.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ private static Window InternalGetCurrentWindow()
internal void RaiseNativeSizeChanged()
{
#if __ANDROID_30__
var (windowBounds, visibleBounds, trueVisibleBounds) = Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.R
? GetVisualBounds()
: GetVisualBoundsLegacy();
#else
var (windowBounds, visibleBounds, trueVisibleBounds) = GetVisualBoundsLegacy();
#endif

ApplicationView.GetForCurrentView()?.SetVisibleBounds(visibleBounds);
ApplicationView.GetForCurrentView()?.SetTrueVisibleBounds(trueVisibleBounds);

if (Bounds != windowBounds)
{
Bounds = windowBounds;

RaiseSizeChanged(
new Windows.UI.Core.WindowSizeChangedEventArgs(
new Windows.Foundation.Size(Bounds.Width, Bounds.Height)
)
);
}
}

#if __ANDROID_30__
private (Rect windowBounds, Rect visibleBounds, Rect trueVisibleBounds) GetVisualBounds()
{
var metrics = (ContextHelper.Current as Activity)?.WindowManager?.CurrentWindowMetrics;

var insetsTypes = WindowInsets.Type.SystemBars(); // == WindowInsets.Type.StatusBars() | WindowInsets.Type.NavigationBars() | WindowInsets.Type.CaptionBar();
Expand All @@ -97,15 +122,17 @@ internal void RaiseNativeSizeChanged()

// The 'metric.Bounds' does not include any insets, so we remove the "solid" insets under which we cannot draw anything
var windowBounds = new Rect(default, ((Rect)metrics.Bounds).DeflateBy(solidInsets).Size).PhysicalToLogicalPixels();
var newBounds = windowBounds;

// The visible bounds is the windows bounds on which we remove also
// [translucent only inset](all_insets - solid_insets_that_has_already_been_removed_from_all_insets)
var visibleBounds = windowBounds.DeflateBy(insets.Minus(solidInsets)).PhysicalToLogicalPixels();

// The true visible bounds ... is unknown for now!
var trueVisibleBounds = visibleBounds;
#else
return (windowBounds, visibleBounds, visibleBounds);
}
#endif

private (Rect windowBounds, Rect visibleBounds, Rect trueVisibleBounds) GetVisualBoundsLegacy()
{
using var display = (ContextHelper.Current as Activity)?.WindowManager?.DefaultDisplay;
using var fullScreenMetrics = new DisplayMetrics();

Expand All @@ -117,11 +144,11 @@ internal void RaiseNativeSizeChanged()

var statusBarSize = GetLogicalStatusBarSize();

var statusBarSizeExcluded = IsStatusBarTranslucent() ?
var statusBarSizeExcluded = IsStatusBarTranslucent()
// The real metrics excluded the StatusBar only if it is plain.
// We want to subtract it if it is translucent. Otherwise, it will be like we subtract it twice.
statusBarSize :
0;
? statusBarSize
: 0;
var navigationBarSizeExcluded = GetLogicalNavigationBarSizeExcluded();

// Actually, we need to check visibility of nav bar and status bar since the insets don't
Expand Down Expand Up @@ -170,21 +197,8 @@ Rect CalculateVisibleBounds(double excludedStatusBarHeight)

var visibleBounds = CalculateVisibleBounds(statusBarSizeExcluded);
var trueVisibleBounds = CalculateVisibleBounds(statusBarSize);
#endif

ApplicationView.GetForCurrentView()?.SetVisibleBounds(visibleBounds);
ApplicationView.GetForCurrentView()?.SetTrueVisibleBounds(trueVisibleBounds);

if (Bounds != newBounds)
{
Bounds = newBounds;

RaiseSizeChanged(
new Windows.UI.Core.WindowSizeChangedEventArgs(
new Windows.Foundation.Size(Bounds.Width, Bounds.Height)
)
);
}
return (newBounds, visibleBounds, trueVisibleBounds);
}

internal void UpdateInsetsWithVisibilities()
Expand Down Expand Up @@ -230,7 +244,6 @@ internal void UpdateInsetsWithVisibilities()
Insets = newInsets;
}

#if !__ANDROID_30__
private double GetLogicalStatusBarSize()
{
var logicalStatusBarHeight = 0d;
Expand Down Expand Up @@ -261,7 +274,6 @@ private double GetLogicalNavigationBarSizeExcluded()
? ViewHelper.PhysicalToLogicalPixels(navigationBarSize)
: 0;
}
#endif

internal void DisplayFullscreen(UIElement element)
{
Expand Down

0 comments on commit 07c3d23

Please sign in to comment.