diff --git a/src/Android/Accessibility/AccessibilityHelpers.cs b/src/Android/Accessibility/AccessibilityHelpers.cs index 112399f79..a304c78e9 100644 --- a/src/Android/Accessibility/AccessibilityHelpers.cs +++ b/src/Android/Accessibility/AccessibilityHelpers.cs @@ -133,12 +133,12 @@ namespace Bit.Droid.Accessibility // Be sure to keep these entries sorted alphabetically public static Dictionary KnownUsernameFields => new List { - new KnownUsernameField("accounts.google.com", "ServiceLogin", "Email"), - new KnownUsernameField("amazon.com", "signin", "ap_email_login"), - new KnownUsernameField("github.com", "", "user[login]-footer"), - new KnownUsernameField("paypal.com", "signin", "email"), - new KnownUsernameField("signin.aws.amazon.com", "signin", "resolving_input"), - new KnownUsernameField("signin.ebay.com", "eBayISAPI.dll", "userid"), + new KnownUsernameField("accounts.google.com", new (string, string)[] { ("ServiceLogin", "Email") }), + new KnownUsernameField("amazon.com", new (string, string)[] { ("signin", "ap_email_login") }), + new KnownUsernameField("github.com", new (string, string)[] { ("", "user[login]-footer") }), + new KnownUsernameField("paypal.com", new (string, string)[] { ("signin", "email") }), + new KnownUsernameField("signin.aws.amazon.com", new (string, string)[] { ("signin", "resolving_input") }), + new KnownUsernameField("signin.ebay.com", new (string, string)[] { ("eBayISAPI.dll", "userid") }), }.ToDictionary(n => n.UriAuthority); public static void PrintTestData(AccessibilityNodeInfo root, AccessibilityEvent e) @@ -314,7 +314,7 @@ namespace Bit.Droid.Accessibility if (Uri.TryCreate(uriString, UriKind.Absolute, out var uri)) { uriAuthority = uri.Authority; - uriKey = uriAuthority.StartsWith("www.") ? uriAuthority.Substring(4) : uriAuthority; + uriKey = uriAuthority.StartsWith("www.", StringComparison.Ordinal) ? uriAuthority.Substring(4) : uriAuthority; uriLocalPath = uri.LocalPath; } @@ -330,15 +330,64 @@ namespace Bit.Droid.Accessibility if (KnownUsernameFields.ContainsKey(uriKey)) { var usernameField = KnownUsernameFields[uriKey]; - if (uriLocalPath.EndsWith(usernameField.UriPathEnd)) + (string UriPathWanted, string UsernameViewId)[] accessOptions = usernameField.AccessOptions; + + for (int i = 0; i < accessOptions.Length; i++) { - foreach (var editText in allEditTexts) + string curUriPathWanted = accessOptions[i].UriPathWanted; + string curUsernameViewId = accessOptions[i].UsernameViewId; + bool uriLocalPathMatches = false; + + // Case-sensitive comparison + if (curUriPathWanted.StartsWith("startswith:", StringComparison.Ordinal)) { - foreach (var usernameViewId in usernameField.UsernameViewId.Split(",")) + curUriPathWanted = curUriPathWanted.Substring(11); + uriLocalPathMatches = uriLocalPath.StartsWith(curUriPathWanted, StringComparison.Ordinal); + } + else if (curUriPathWanted.StartsWith("contains:", StringComparison.Ordinal)) + { + curUriPathWanted = curUriPathWanted.Substring(9); + uriLocalPathMatches = uriLocalPath.Contains(curUriPathWanted, StringComparison.Ordinal); + } + else if (curUriPathWanted.StartsWith("endswith:", StringComparison.Ordinal)) + { + curUriPathWanted = curUriPathWanted.Substring(9); + uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.Ordinal); + } + + // Case-insensitive comparison + else if (curUriPathWanted.StartsWith("istartswith:", StringComparison.Ordinal)) + { + curUriPathWanted = curUriPathWanted.Substring(12); + uriLocalPathMatches = uriLocalPath.StartsWith(curUriPathWanted, StringComparison.OrdinalIgnoreCase); + } + else if (curUriPathWanted.StartsWith("icontains:", StringComparison.Ordinal)) + { + curUriPathWanted = curUriPathWanted.Substring(10); + uriLocalPathMatches = uriLocalPath.Contains(curUriPathWanted, StringComparison.OrdinalIgnoreCase); + } + else if (curUriPathWanted.StartsWith("iendswith:", StringComparison.Ordinal)) + { + curUriPathWanted = curUriPathWanted.Substring(10); + uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.OrdinalIgnoreCase); + } + + // Default type of comparison + else + { + uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.Ordinal); + } + + if (uriLocalPathMatches) + { + foreach (var editText in allEditTexts) { - if (usernameViewId == editText.ViewIdResourceName) + foreach (var usernameViewId in curUsernameViewId.Split(",")) { - return editText; + if (usernameViewId == editText.ViewIdResourceName) + { + return editText; + } } } } diff --git a/src/Android/Accessibility/KnownUsernameField.cs b/src/Android/Accessibility/KnownUsernameField.cs index 2cd6a9193..f8db476fe 100644 --- a/src/Android/Accessibility/KnownUsernameField.cs +++ b/src/Android/Accessibility/KnownUsernameField.cs @@ -2,15 +2,13 @@ { public class KnownUsernameField { - public KnownUsernameField(string uriAuthority, string uriPathEnd, string usernameViewId) + public KnownUsernameField(string uriAuthority, (string UriPathWanted, string UsernameViewId)[] accessOptions) { UriAuthority = uriAuthority; - UriPathEnd = uriPathEnd; - UsernameViewId = usernameViewId; + AccessOptions = accessOptions; } public string UriAuthority { get; set; } - public string UriPathEnd { get; set; } - public string UsernameViewId { get; set; } + public (string UriPathWanted, string UsernameViewId)[] AccessOptions { get; set; } } }