diff --git a/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.Android.cs index e124e6b4a66c..d1110c4ce3ad 100644 --- a/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.Android.cs @@ -207,5 +207,79 @@ await InvokeOnMainThreadAsync(() => AssertTranslationMatches(nativeView, entry.TranslationX, entry.TranslationY); }); } + + [Fact] + [Category(TestCategory.Entry)] + public async Task KeyboardPasswordDoesNotForcePasswordVisibilityWhenIsPasswordFalse() + { + var entry = new Entry + { + Keyboard = Keyboard.Password, + IsPassword = false, + Text = "Password" + }; + + var handler = await CreateHandlerAsync(entry); + var platformEntry = GetPlatformControl(handler); + + await InvokeOnMainThreadAsync(() => + { + Assert.False(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.TextVariationPassword)); + Assert.False(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.NumberVariationPassword)); + }); + } + + [Fact] + [Category(TestCategory.Entry)] + public async Task KeyboardPasswordRespectsIsPasswordToggle() + { + var entry = new Entry + { + Keyboard = Keyboard.Password, + IsPassword = false, + Text = "Password" + }; + + var handler = await CreateHandlerAsync(entry); + var platformEntry = GetPlatformControl(handler); + + await InvokeOnMainThreadAsync(() => + { + Assert.False(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.TextVariationPassword)); + + entry.IsPassword = true; + handler.UpdateValue(nameof(IEntry.IsPassword)); + + Assert.True(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.TextVariationPassword)); + + entry.IsPassword = false; + handler.UpdateValue(nameof(IEntry.IsPassword)); + + Assert.False(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.TextVariationPassword)); + Assert.False(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.NumberVariationPassword)); + }); + } + + [Fact] + [Category(TestCategory.Entry)] + public async Task KeyboardUrlPreservesUrlInputTypeWhenIsPasswordFalse() + { + var entry = new Entry + { + Keyboard = Keyboard.Url, + IsPassword = false, + Text = "https://dot.net" + }; + + var handler = await CreateHandlerAsync(entry); + var platformEntry = GetPlatformControl(handler); + + await InvokeOnMainThreadAsync(() => + { + Assert.True(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.ClassText)); + Assert.True(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.TextVariationUri)); + Assert.False(platformEntry.InputType.HasFlag(global::Android.Text.InputTypes.TextVariationPassword)); + }); + } } } diff --git a/src/Core/src/Platform/Android/EditTextExtensions.cs b/src/Core/src/Platform/Android/EditTextExtensions.cs index a81674d035eb..91c8fd93a786 100644 --- a/src/Core/src/Platform/Android/EditTextExtensions.cs +++ b/src/Core/src/Platform/Android/EditTextExtensions.cs @@ -375,12 +375,24 @@ internal static void SetInputType(this EditText editText, ITextInput textInput) editText.KeyListener = LocalizedDigitsKeyListener.Create(editText.InputType); } - if (textInput is IEntry entry && entry.IsPassword) + if (textInput is IEntry entry) { - if (editText.InputType.HasFlag(InputTypes.ClassText)) - editText.InputType |= InputTypes.TextVariationPassword; - if (editText.InputType.HasFlag(InputTypes.ClassNumber)) - editText.InputType |= InputTypes.NumberVariationPassword; + if (entry.IsPassword) + { + if (editText.InputType.HasFlag(InputTypes.ClassText)) + editText.InputType |= InputTypes.TextVariationPassword; + + if (editText.InputType.HasFlag(InputTypes.ClassNumber)) + editText.InputType |= InputTypes.NumberVariationPassword; + } + else + { + if (editText.InputType.HasFlag(InputTypes.ClassText)) + editText.InputType &= ~InputTypes.TextVariationPassword; + + if (editText.InputType.HasFlag(InputTypes.ClassNumber)) + editText.InputType &= ~InputTypes.NumberVariationPassword; + } } if (textInput is IEditor)