bitwarden-android/src/Android/Autofill/Parser.cs

130 lines
3.9 KiB
C#
Raw Normal View History

using static Android.App.Assist.AssistStructure;
using Android.App.Assist;
2017-11-18 01:15:42 +03:00
using Bit.App;
using System.Collections.Generic;
namespace Bit.Android.Autofill
{
public class Parser
{
public static HashSet<string> TrustedBrowsers = new HashSet<string>
{
"org.mozilla.focus","org.mozilla.firefox","org.mozilla.firefox_beta","com.microsoft.emmx",
"com.android.chrome","com.chrome.beta","com.android.browser","com.brave.browser","com.opera.browser",
"com.opera.browser.beta","com.opera.mini.native","com.chrome.dev","com.chrome.canary",
"com.google.android.apps.chrome","com.google.android.apps.chrome_dev","com.yandex.browser",
"com.sec.android.app.sbrowser","com.sec.android.app.sbrowser.beta","org.codeaurora.swe.browser",
2018-01-26 16:56:43 +03:00
"com.amazon.cloud9","org.mozilla.klar", "com.duckduckgo.mobile.android"
};
private readonly AssistStructure _structure;
private string _uri;
private string _packageName;
private string _webDomain;
public Parser(AssistStructure structure)
{
_structure = structure;
}
public FieldCollection FieldCollection { get; private set; } = new FieldCollection();
public string Uri
{
get
{
if(!string.IsNullOrWhiteSpace(_uri))
{
return _uri;
}
if(string.IsNullOrWhiteSpace(WebDomain) && string.IsNullOrWhiteSpace(PackageName))
{
_uri = null;
}
else if(!string.IsNullOrWhiteSpace(WebDomain))
{
_uri = string.Concat("http://", WebDomain);
}
else
{
_uri = string.Concat(Constants.AndroidAppProtocol, PackageName);
}
return _uri;
}
}
public string PackageName
{
get => _packageName;
set
{
2017-11-17 18:09:27 +03:00
if(string.IsNullOrWhiteSpace(value))
{
_packageName = _uri = null;
2017-11-17 18:09:27 +03:00
}
_packageName = value;
}
}
public string WebDomain
{
get => _webDomain;
set
{
if(string.IsNullOrWhiteSpace(value))
{
_webDomain = _uri = null;
}
_webDomain = value;
}
}
2017-11-18 01:15:42 +03:00
public void Parse()
{
for(var i = 0; i < _structure.WindowNodeCount; i++)
{
var node = _structure.GetWindowNodeAt(i);
2017-11-18 01:15:42 +03:00
ParseNode(node.RootViewNode);
}
2018-01-26 16:56:43 +03:00
if(!TrustedBrowsers.Contains(PackageName))
{
WebDomain = null;
}
}
2017-11-18 01:15:42 +03:00
private void ParseNode(ViewNode node)
{
2017-11-17 05:58:04 +03:00
var hints = node.GetAutofillHints();
var isEditText = node.ClassName == "android.widget.EditText" || node?.HtmlInfo?.Tag == "input";
2017-11-17 05:58:04 +03:00
if(isEditText || (hints?.Length ?? 0) > 0)
{
2018-01-26 16:56:43 +03:00
if(string.IsNullOrWhiteSpace(PackageName))
{
PackageName = node.IdPackage;
}
2018-01-26 16:56:43 +03:00
if(string.IsNullOrWhiteSpace(WebDomain))
{
WebDomain = node.WebDomain;
}
2017-11-18 01:15:42 +03:00
FieldCollection.Add(new Field(node));
}
2017-11-18 07:26:51 +03:00
else
{
2018-01-26 16:56:43 +03:00
if(string.IsNullOrWhiteSpace(WebDomain))
{
WebDomain = node.WebDomain;
}
2017-11-18 07:26:51 +03:00
FieldCollection.IgnoreAutofillIds.Add(node.AutofillId);
}
2017-11-17 05:58:04 +03:00
for(var i = 0; i < node.ChildCount; i++)
{
2017-11-18 01:15:42 +03:00
ParseNode(node.GetChildAt(i));
}
}
}
}