-
Notifications
You must be signed in to change notification settings - Fork 395
Description
Library version used
4.78.0
.NET version
Platform: Android (MAUI)
Target Framework: net9.0-android
Scenario
Other - please specify
Is this a new or an existing app?
The app is in production, I haven't upgraded MSAL, but started seeing this issue
Issue description and reproduction steps
When using AcquireTokenInteractive with an embedded WebView (WithUseEmbeddedWebView(true)) on Android, tapping on input fields (username/password) causes the keyboard to appear with a large white/blank space above it. The white space height is approximately equal to the keyboard height.
Steps to Reproduce
1. Configure MSAL with embedded WebView:
result = await _pca.AcquireTokenInteractive(scopes)
.WithParentActivityOrWindow(parentWindow)
.WithUseEmbeddedWebView(true)
.ExecuteAsync();
2. Launch the interactive authentication flow
3. When the login page appears, tap on the username or password input field
Observe the keyboard appearing with a large white space above it
The white space is scrollable with the page itself. When the keyboard is hidden then the white gap disappears.
Test phones used:
- Samsung Galaxy A56
- Pixel 4a
Relevant code snippets
Expected behavior
Expected Behavior
The keyboard should appear normally without any white space between the keyboard and the WebView content. The WebView should resize or pan correctly to accommodate the keyboard.
Actual Behavior
A white/blank space appears above the keyboard. The space height is approximately equal to the keyboard height, suggesting the bottom inset is being applied twice.
Identity provider
Azure B2C Custom Policy
Regression
We used the same 4.78.0 version but we didn't notice this behavior before
Solution and workarounds
After investigation, the issue appears to be in how AuthenticationAgentActivity handles window insets. The activity uses edge-to-edge layout with SetDecorFitsSystemWindows(false) and implements OnApplyWindowInsetsListener.
When the keyboard (IME) appears, both system bar insets and IME insets are reported. The current implementation appears to cause double-application of the bottom inset:
• System bar bottom inset (navigation bar height, ~48dp)
• IME bottom inset (keyboard height, ~300dp)
When combined or applied sequentially, this results in excessive bottom spacing.
Workaround
We implemented a workaround by overriding the WebView's inset listener via ActivityLifecycleCallbacks:
// In MainApplication.cs
protected override MauiApp CreateMauiApp()
{
RegisterActivityLifecycleCallbacks(new MsalActivityLifecycleCallbacks());
// ...
}
private class MsalActivityLifecycleCallbacks : Java.Lang.Object, Android.App.Application.IActivityLifecycleCallbacks
{
private const string MsalActivityName = "AuthenticationAgentActivity";
public void OnActivityResumed(Activity activity)
{
if (activity.GetType().Name.Contains(MsalActivityName) && activity.Window != null)
{
var webView = FindWebView(activity.Window.DecorView);
if (webView is not null)
{
ViewCompat.SetOnApplyWindowInsetsListener(webView, new MsalWebViewInsetsListener());
}
}
}
// Other interface methods...
private static Android.Webkit.WebView? FindWebView(Android.Views.View? view)
{
if (view == null) return null;
if (view is Android.Webkit.WebView webView) return webView;
if (view is ViewGroup viewGroup)
{
for (int i = 0; i < viewGroup.ChildCount; i++)
{
var result = FindWebView(viewGroup.GetChildAt(i));
if (result is not null) return result;
}
}
return null;
}
}
private class MsalWebViewInsetsListener : Java.Lang.Object, IOnApplyWindowInsetsListener
{
public WindowInsetsCompat OnApplyWindowInsets(Android.Views.View? view, WindowInsetsCompat? insets)
{
if (view == null || insets == null)
return insets ?? new WindowInsetsCompat.Builder().Build();
var systemBars = insets.GetInsets(WindowInsetsCompat.Type.SystemBars());
var ime = insets.GetInsets(WindowInsetsCompat.Type.Ime());
var isKeyboardVisible = insets.IsVisible(WindowInsetsCompat.Type.Ime());
// Key fix: use only ONE source for bottom inset, not both
int bottomMargin = isKeyboardVisible ? ime.Bottom : systemBars.Bottom;
if (view.LayoutParameters is ViewGroup.MarginLayoutParams marginParams)
{
marginParams.LeftMargin = systemBars.Left;
marginParams.TopMargin = systemBars.Top;
marginParams.RightMargin = systemBars.Right;
marginParams.BottomMargin = bottomMargin;
view.LayoutParameters = marginParams;
}
return WindowInsetsCompat.Consumed;
}
}
The key fix is using only the IME bottom inset when the keyboard is visible, or only the system bar bottom inset when it's hidden - never combining both.

