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

87 lines
2.4 KiB
C#
Raw Normal View History

using static Android.App.Assist.AssistStructure;
using Android.App.Assist;
namespace Bit.Android.Autofill
{
public class Parser
{
private readonly AssistStructure _structure;
private string _uri;
private FilledFieldCollection _filledAutofillFieldCollection;
public Parser(AssistStructure structure)
{
_structure = structure;
}
public FieldCollection FieldCollection { get; private set; } = new FieldCollection();
public string Uri
{
get => _uri;
set
{
_uri = $"androidapp://{value}";
}
}
public void ParseForFill()
{
Parse(true);
}
public void ParseForSave()
{
Parse(false);
}
/**
* Traverse AssistStructure and add ViewNode metadata to a flat list.
*/
private void Parse(bool forFill)
{
_filledAutofillFieldCollection = new FilledFieldCollection();
for(var i = 0; i < _structure.WindowNodeCount; i++)
{
var node = _structure.GetWindowNodeAt(i);
var view = node.RootViewNode;
ParseLocked(forFill, view);
}
}
private void ParseLocked(bool forFill, ViewNode viewNode)
{
var autofillHints = viewNode.GetAutofillHints();
var autofillType = viewNode.AutofillType;
var inputType = viewNode.InputType;
var isEditText = viewNode.ClassName == "android.widget.EditText";
if(isEditText || (autofillHints?.Length ?? 0) > 0)
{
if(forFill)
{
var f = new Field(viewNode);
FieldCollection.Add(f);
if(Uri == null)
{
Uri = viewNode.IdPackage;
}
}
else
{
_filledAutofillFieldCollection.Add(new FilledField(viewNode));
}
}
for(var i = 0; i < viewNode.ChildCount; i++)
{
ParseLocked(forFill, viewNode.GetChildAt(i));
}
}
public FilledFieldCollection GetClientFormData()
{
return _filledAutofillFieldCollection;
}
}
}