mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 23:25:45 +03:00
add old autofill implementation for reference.
This commit is contained in:
parent
36ee3aaec6
commit
849ec6fa8f
4 changed files with 891 additions and 220 deletions
|
@ -287,6 +287,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AutofillActivity.cs" />
|
<Compile Include="AutofillActivity.cs" />
|
||||||
<Compile Include="AutofillCredentials.cs" />
|
<Compile Include="AutofillCredentials.cs" />
|
||||||
|
<Compile Include="AutofillFrameworkService_OLD.cs" />
|
||||||
<Compile Include="AutofillFrameworkService.cs" />
|
<Compile Include="AutofillFrameworkService.cs" />
|
||||||
<Compile Include="Controls\CustomLabelRenderer.cs" />
|
<Compile Include="Controls\CustomLabelRenderer.cs" />
|
||||||
<Compile Include="Controls\CustomSearchBarRenderer.cs" />
|
<Compile Include="Controls\CustomSearchBarRenderer.cs" />
|
||||||
|
@ -342,6 +343,9 @@
|
||||||
<AndroidResource Include="Resources\layout\toolbar.axml">
|
<AndroidResource Include="Resources\layout\toolbar.axml">
|
||||||
<SubType>AndroidResource</SubType>
|
<SubType>AndroidResource</SubType>
|
||||||
</AndroidResource>
|
</AndroidResource>
|
||||||
|
<AndroidResource Include="Resources\layout\autofill_listitem.axml">
|
||||||
|
<SubType>AndroidResource</SubType>
|
||||||
|
</AndroidResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Properties\AndroidManifest.xml" />
|
<None Include="Properties\AndroidManifest.xml" />
|
||||||
|
|
630
src/Android/AutofillFrameworkService_OLD.cs
Normal file
630
src/Android/AutofillFrameworkService_OLD.cs
Normal file
|
@ -0,0 +1,630 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.OS;
|
||||||
|
using Android.Runtime;
|
||||||
|
using Android.Service.Autofill;
|
||||||
|
using Android.Views;
|
||||||
|
using Android.Widget;
|
||||||
|
using Android.Views.Autofill;
|
||||||
|
using static Android.App.Assist.AssistStructure;
|
||||||
|
using Android.Text;
|
||||||
|
using Android.App.Assist;
|
||||||
|
|
||||||
|
namespace Bit.Android
|
||||||
|
{
|
||||||
|
//[Service(Permission = global::Android.Manifest.Permission.BindAutofillService, Label = "bitwarden")]
|
||||||
|
//[IntentFilter(new string[] { "android.service.autofill.AutofillService" })]
|
||||||
|
//[MetaData("android.autofill", Resource = "@xml/autofillservice")]
|
||||||
|
public class AutofillFrameworkService_OLD : global::Android.Service.Autofill.AutofillService
|
||||||
|
{
|
||||||
|
public override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal,
|
||||||
|
FillCallback callback)
|
||||||
|
{
|
||||||
|
var structure = request.FillContexts?.LastOrDefault()?.Structure;
|
||||||
|
if(structure == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var clientState = request.ClientState;
|
||||||
|
|
||||||
|
var parser = new StructureParser(structure);
|
||||||
|
parser.ParseForFill();
|
||||||
|
|
||||||
|
// build response
|
||||||
|
var responseBuilder = new FillResponse.Builder();
|
||||||
|
|
||||||
|
var username1 = new FilledAutofillField { TextValue = "username1" };
|
||||||
|
var password1 = new FilledAutofillField { TextValue = "pass1" };
|
||||||
|
var login1 = new Dictionary<string, FilledAutofillField>
|
||||||
|
{
|
||||||
|
{ View.AutofillHintUsername, username1 },
|
||||||
|
{ View.AutofillHintPassword, password1 }
|
||||||
|
};
|
||||||
|
var coll = new FilledAutofillFieldCollection("Login 1 Name", login1);
|
||||||
|
|
||||||
|
var username2 = new FilledAutofillField { TextValue = "username2" };
|
||||||
|
var password2 = new FilledAutofillField { TextValue = "pass2" };
|
||||||
|
var login2 = new Dictionary<string, FilledAutofillField>
|
||||||
|
{
|
||||||
|
{ View.AutofillHintUsername, username2 },
|
||||||
|
{ View.AutofillHintPassword, password2 }
|
||||||
|
};
|
||||||
|
var col2 = new FilledAutofillFieldCollection("Login 2 Name", login2);
|
||||||
|
|
||||||
|
var clientFormDataMap = new Dictionary<string, FilledAutofillFieldCollection>
|
||||||
|
{
|
||||||
|
{ "login-1-guid", coll },
|
||||||
|
{ "login-2-guid", col2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = AutofillHelper.NewResponse(this, false, parser.AutofillFields, clientFormDataMap);
|
||||||
|
// end build response
|
||||||
|
|
||||||
|
callback.OnSuccess(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnSaveRequest(SaveRequest request, SaveCallback callback)
|
||||||
|
{
|
||||||
|
var structure = request.FillContexts?.LastOrDefault()?.Structure;
|
||||||
|
if(structure == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var clientState = request.ClientState;
|
||||||
|
|
||||||
|
var parser = new StructureParser(structure);
|
||||||
|
parser.ParseForSave();
|
||||||
|
var filledAutofillFieldCollection = parser.GetClientFormData();
|
||||||
|
//SaveFilledAutofillFieldCollection(filledAutofillFieldCollection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////// Helper Classes ///////////////////////
|
||||||
|
|
||||||
|
public class StructureParser
|
||||||
|
{
|
||||||
|
private readonly AssistStructure _structure;
|
||||||
|
private FilledAutofillFieldCollection _filledAutofillFieldCollection;
|
||||||
|
|
||||||
|
public StructureParser(AssistStructure structure)
|
||||||
|
{
|
||||||
|
_structure = structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutofillFieldMetadataCollection AutofillFields { get; private set; }
|
||||||
|
= new AutofillFieldMetadataCollection();
|
||||||
|
|
||||||
|
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 FilledAutofillFieldCollection();
|
||||||
|
|
||||||
|
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 = (AutofillType)(int)viewNode.AutofillType;
|
||||||
|
var inputType = (InputTypes)(int)viewNode.InputType;
|
||||||
|
var isEditText = viewNode.ClassName == "android.widget.EditText";
|
||||||
|
if(isEditText || (autofillHints?.Length ?? 0) > 0)
|
||||||
|
{
|
||||||
|
if(forFill)
|
||||||
|
{
|
||||||
|
AutofillFields.Add(new AutofillFieldMetadata(viewNode));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filledAutofillFieldCollection.Add(new FilledAutofillField(viewNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < viewNode.ChildCount; i++)
|
||||||
|
{
|
||||||
|
ParseLocked(forFill, viewNode.GetChildAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilledAutofillFieldCollection GetClientFormData()
|
||||||
|
{
|
||||||
|
return _filledAutofillFieldCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AutofillFieldMetadataCollection
|
||||||
|
{
|
||||||
|
private int _size = 0;
|
||||||
|
|
||||||
|
public List<int> Ids { get; private set; } = new List<int>();
|
||||||
|
public List<AutofillId> AutofillIds { get; private set; } = new List<AutofillId>();
|
||||||
|
public SaveDataType SaveType { get; private set; } = SaveDataType.Generic;
|
||||||
|
public List<string> AutofillHints { get; private set; } = new List<string>();
|
||||||
|
public List<string> FocusedAutofillHints { get; private set; } = new List<string>();
|
||||||
|
public List<AutofillFieldMetadata> Feilds { get; private set; }
|
||||||
|
public IDictionary<int, AutofillFieldMetadata> IdToFieldMap { get; private set; } =
|
||||||
|
new Dictionary<int, AutofillFieldMetadata>();
|
||||||
|
public IDictionary<string, List<AutofillFieldMetadata>> AutofillHintsToFieldsMap { get; private set; } =
|
||||||
|
new Dictionary<string, List<AutofillFieldMetadata>>();
|
||||||
|
|
||||||
|
public void Add(AutofillFieldMetadata data)
|
||||||
|
{
|
||||||
|
_size++;
|
||||||
|
SaveType |= data.SaveType;
|
||||||
|
Ids.Add(data.Id);
|
||||||
|
AutofillIds.Add(data.AutofillId);
|
||||||
|
IdToFieldMap.Add(data.Id, data);
|
||||||
|
|
||||||
|
if((data.AutofillHints?.Count ?? 0) > 0)
|
||||||
|
{
|
||||||
|
AutofillHints.AddRange(data.AutofillHints);
|
||||||
|
if(data.IsFocused)
|
||||||
|
{
|
||||||
|
FocusedAutofillHints.AddRange(data.AutofillHints);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var hint in data.AutofillHints)
|
||||||
|
{
|
||||||
|
if(!AutofillHintsToFieldsMap.ContainsKey(hint))
|
||||||
|
{
|
||||||
|
AutofillHintsToFieldsMap.Add(hint, new List<AutofillFieldMetadata>());
|
||||||
|
}
|
||||||
|
|
||||||
|
AutofillHintsToFieldsMap[hint].Add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AutofillFieldMetadata
|
||||||
|
{
|
||||||
|
private List<string> _autofillHints;
|
||||||
|
private string[] _autofillOptions;
|
||||||
|
|
||||||
|
public AutofillFieldMetadata(ViewNode view)
|
||||||
|
{
|
||||||
|
_autofillOptions = view.GetAutofillOptions();
|
||||||
|
Id = view.Id;
|
||||||
|
AutofillId = view.AutofillId;
|
||||||
|
AutofillType = (AutofillType)(int)view.AutofillType;
|
||||||
|
InputType = (InputTypes)(int)view.InputType;
|
||||||
|
IsFocused = view.IsFocused;
|
||||||
|
AutofillHints = AutofillHelper.FilterForSupportedHints(view.GetAutofillHints())?.ToList() ?? new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaveDataType SaveType { get; set; } = SaveDataType.Generic;
|
||||||
|
public List<string> AutofillHints
|
||||||
|
{
|
||||||
|
get { return _autofillHints; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_autofillHints = value;
|
||||||
|
UpdateSaveTypeFromHints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int Id { get; private set; }
|
||||||
|
public AutofillId AutofillId { get; private set; }
|
||||||
|
public AutofillType AutofillType { get; private set; }
|
||||||
|
public InputTypes InputType { get; private set; }
|
||||||
|
public bool IsFocused { get; private set; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the {@link ViewNode} is a list that the user needs to choose a string from (i.e. a
|
||||||
|
* spinner), this is called to return the index of a specific item in the list.
|
||||||
|
*/
|
||||||
|
public int GetAutofillOptionIndex(string value)
|
||||||
|
{
|
||||||
|
for(var i = 0; i < _autofillOptions.Length; i++)
|
||||||
|
{
|
||||||
|
if(_autofillOptions[i].Equals(value))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSaveTypeFromHints()
|
||||||
|
{
|
||||||
|
SaveType = SaveDataType.Generic;
|
||||||
|
if(_autofillHints == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var hint in _autofillHints)
|
||||||
|
{
|
||||||
|
switch(hint)
|
||||||
|
{
|
||||||
|
case View.AutofillHintCreditCardExpirationDate:
|
||||||
|
case View.AutofillHintCreditCardExpirationDay:
|
||||||
|
case View.AutofillHintCreditCardExpirationMonth:
|
||||||
|
case View.AutofillHintCreditCardExpirationYear:
|
||||||
|
case View.AutofillHintCreditCardNumber:
|
||||||
|
case View.AutofillHintCreditCardSecurityCode:
|
||||||
|
SaveType |= SaveDataType.CreditCard;
|
||||||
|
break;
|
||||||
|
case View.AutofillHintEmailAddress:
|
||||||
|
SaveType |= SaveDataType.EmailAddress;
|
||||||
|
break;
|
||||||
|
case View.AutofillHintPhone:
|
||||||
|
case View.AutofillHintName:
|
||||||
|
SaveType |= SaveDataType.Generic;
|
||||||
|
break;
|
||||||
|
case View.AutofillHintPassword:
|
||||||
|
SaveType |= SaveDataType.Password;
|
||||||
|
SaveType &= ~SaveDataType.EmailAddress;
|
||||||
|
SaveType &= ~SaveDataType.Username;
|
||||||
|
break;
|
||||||
|
case View.AutofillHintPostalAddress:
|
||||||
|
case View.AutofillHintPostalCode:
|
||||||
|
SaveType |= SaveDataType.Address;
|
||||||
|
break;
|
||||||
|
case View.AutofillHintUsername:
|
||||||
|
SaveType |= SaveDataType.Username;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilledAutofillField
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Does not need to be serialized into persistent storage, so it's not exposed.
|
||||||
|
*/
|
||||||
|
private string[] _autofillHints = null;
|
||||||
|
|
||||||
|
public FilledAutofillField() { }
|
||||||
|
|
||||||
|
public FilledAutofillField(ViewNode viewNode)
|
||||||
|
{
|
||||||
|
_autofillHints = AutofillHelper.FilterForSupportedHints(viewNode.GetAutofillHints());
|
||||||
|
var autofillValue = viewNode.AutofillValue;
|
||||||
|
if(autofillValue != null)
|
||||||
|
{
|
||||||
|
if(autofillValue.IsList)
|
||||||
|
{
|
||||||
|
var autofillOptions = viewNode.GetAutofillOptions();
|
||||||
|
int index = autofillValue.ListValue;
|
||||||
|
if(autofillOptions != null && autofillOptions.Length > 0)
|
||||||
|
{
|
||||||
|
TextValue = autofillOptions[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(autofillValue.IsDate)
|
||||||
|
{
|
||||||
|
DateValue = autofillValue.DateValue;
|
||||||
|
}
|
||||||
|
else if(autofillValue.IsText)
|
||||||
|
{
|
||||||
|
// Using toString of AutofillValue.getTextValue in order to save it to
|
||||||
|
// SharedPreferences.
|
||||||
|
TextValue = autofillValue.TextValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TextValue { get; set; }
|
||||||
|
public long? DateValue { get; set; }
|
||||||
|
public bool? ToggleValue { get; set; }
|
||||||
|
|
||||||
|
public string[] GetAutofillHints()
|
||||||
|
{
|
||||||
|
return _autofillHints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsNull()
|
||||||
|
{
|
||||||
|
return TextValue == null && DateValue == null && ToggleValue == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object o)
|
||||||
|
{
|
||||||
|
if(this == o)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(o == null || GetType() != o.GetType())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var that = (FilledAutofillField)o;
|
||||||
|
if(TextValue != null ? !TextValue.Equals(that.TextValue) : that.TextValue != null)
|
||||||
|
return false;
|
||||||
|
if(DateValue != null ? !DateValue.Equals(that.DateValue) : that.DateValue != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ToggleValue != null ? ToggleValue.Equals(that.ToggleValue) : that.ToggleValue == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
var result = TextValue != null ? TextValue.GetHashCode() : 0;
|
||||||
|
result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
|
||||||
|
result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilledAutofillFieldCollection
|
||||||
|
{
|
||||||
|
public FilledAutofillFieldCollection()
|
||||||
|
: this(null, new Dictionary<string, FilledAutofillField>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilledAutofillFieldCollection(string datasetName, IDictionary<string, FilledAutofillField> hintMap)
|
||||||
|
{
|
||||||
|
HintMap = hintMap;
|
||||||
|
DatasetName = datasetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, FilledAutofillField> HintMap { get; private set; }
|
||||||
|
public string DatasetName { get; set; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@code FilledAutofillField} to the collection, indexed by all of its hints.
|
||||||
|
*/
|
||||||
|
public void Add(FilledAutofillField filledAutofillField)
|
||||||
|
{
|
||||||
|
if(filledAutofillField == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(filledAutofillField));
|
||||||
|
}
|
||||||
|
|
||||||
|
var autofillHints = filledAutofillField.GetAutofillHints();
|
||||||
|
foreach(var hint in autofillHints)
|
||||||
|
{
|
||||||
|
HintMap.Add(hint, filledAutofillField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates a {@link Dataset.Builder} with appropriate values for each {@link AutofillId}
|
||||||
|
* in a {@code AutofillFieldMetadataCollection}.
|
||||||
|
*
|
||||||
|
* In other words, it constructs an autofill
|
||||||
|
* {@link Dataset.Builder} by applying saved values (from this {@code FilledAutofillFieldCollection})
|
||||||
|
* to Views specified in a {@code AutofillFieldMetadataCollection}, which represents the current
|
||||||
|
* page the user is on.
|
||||||
|
*/
|
||||||
|
public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection,
|
||||||
|
Dataset.Builder datasetBuilder)
|
||||||
|
{
|
||||||
|
var setValueAtLeastOnce = false;
|
||||||
|
var allHints = autofillFieldMetadataCollection.AutofillHints;
|
||||||
|
for(var hintIndex = 0; hintIndex < allHints.Count; hintIndex++)
|
||||||
|
{
|
||||||
|
var hint = allHints[hintIndex];
|
||||||
|
if(!autofillFieldMetadataCollection.AutofillHintsToFieldsMap.ContainsKey(hint))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fillableAutofillFields = autofillFieldMetadataCollection.AutofillHintsToFieldsMap[hint];
|
||||||
|
for(var autofillFieldIndex = 0; autofillFieldIndex < fillableAutofillFields.Count; autofillFieldIndex++)
|
||||||
|
{
|
||||||
|
if(!HintMap.ContainsKey(hint))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filledAutofillField = HintMap[hint];
|
||||||
|
var autofillFieldMetadata = fillableAutofillFields[autofillFieldIndex];
|
||||||
|
var autofillId = autofillFieldMetadata.AutofillId;
|
||||||
|
var autofillType = autofillFieldMetadata.AutofillType;
|
||||||
|
switch(autofillType)
|
||||||
|
{
|
||||||
|
case AutofillType.List:
|
||||||
|
int listValue = autofillFieldMetadata.GetAutofillOptionIndex(filledAutofillField.TextValue);
|
||||||
|
if(listValue != -1)
|
||||||
|
{
|
||||||
|
datasetBuilder.SetValue(autofillId, AutofillValue.ForList(listValue));
|
||||||
|
setValueAtLeastOnce = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AutofillType.Date:
|
||||||
|
var dateValue = filledAutofillField.DateValue;
|
||||||
|
if(dateValue != null)
|
||||||
|
{
|
||||||
|
datasetBuilder.SetValue(autofillId, AutofillValue.ForDate(dateValue.Value));
|
||||||
|
setValueAtLeastOnce = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AutofillType.Text:
|
||||||
|
var textValue = filledAutofillField.TextValue;
|
||||||
|
if(textValue != null)
|
||||||
|
{
|
||||||
|
datasetBuilder.SetValue(autofillId, AutofillValue.ForText(textValue));
|
||||||
|
setValueAtLeastOnce = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AutofillType.Toggle:
|
||||||
|
var toggleValue = filledAutofillField.ToggleValue;
|
||||||
|
if(toggleValue != null)
|
||||||
|
{
|
||||||
|
datasetBuilder.SetValue(autofillId, AutofillValue.ForToggle(toggleValue.Value));
|
||||||
|
setValueAtLeastOnce = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AutofillType.None:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return setValueAtLeastOnce;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes in a list of autofill hints (`autofillHints`), usually associated with a View or set of
|
||||||
|
* Views. Returns whether any of the filled fields on the page have at least 1 of these
|
||||||
|
* `autofillHint`s.
|
||||||
|
*/
|
||||||
|
public bool HelpsWithHints(List<String> autofillHints)
|
||||||
|
{
|
||||||
|
for(var i = 0; i < autofillHints.Count; i++)
|
||||||
|
{
|
||||||
|
if(HintMap.ContainsKey(autofillHints[i]) && !HintMap[autofillHints[i]].IsNull())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AutofillHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Wraps autofill data in a LoginCredential Dataset object which can then be sent back to the
|
||||||
|
* client View.
|
||||||
|
*/
|
||||||
|
public static Dataset NewDataset(Context context, AutofillFieldMetadataCollection autofillFields,
|
||||||
|
FilledAutofillFieldCollection filledAutofillFieldCollection, bool datasetAuth)
|
||||||
|
{
|
||||||
|
var datasetName = filledAutofillFieldCollection.DatasetName;
|
||||||
|
if(datasetName != null)
|
||||||
|
{
|
||||||
|
Dataset.Builder datasetBuilder;
|
||||||
|
if(datasetAuth)
|
||||||
|
{
|
||||||
|
datasetBuilder = new Dataset.Builder(
|
||||||
|
NewRemoteViews(context.PackageName, datasetName, "username", Resource.Drawable.fa_lock));
|
||||||
|
//IntentSender sender = AuthActivity.getAuthIntentSenderForDataset(context, datasetName);
|
||||||
|
//datasetBuilder.SetAuthentication(sender);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
datasetBuilder = new Dataset.Builder(
|
||||||
|
NewRemoteViews(context.PackageName, datasetName, "username", Resource.Drawable.user));
|
||||||
|
}
|
||||||
|
|
||||||
|
var setValueAtLeastOnce = filledAutofillFieldCollection.ApplyToFields(autofillFields, datasetBuilder);
|
||||||
|
if(setValueAtLeastOnce)
|
||||||
|
{
|
||||||
|
return datasetBuilder.Build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RemoteViews NewRemoteViews(string packageName, string text, string subtext, int iconId)
|
||||||
|
{
|
||||||
|
var views = new RemoteViews(packageName, Resource.Layout.autofill_listitem);
|
||||||
|
views.SetTextViewText(Resource.Id.text, text);
|
||||||
|
views.SetTextViewText(Resource.Id.text2, subtext);
|
||||||
|
views.SetImageViewResource(Resource.Id.icon, iconId);
|
||||||
|
return views;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps autofill data in a Response object (essentially a series of Datasets) which can then
|
||||||
|
* be sent back to the client View.
|
||||||
|
*/
|
||||||
|
public static FillResponse NewResponse(Context context, bool datasetAuth,
|
||||||
|
AutofillFieldMetadataCollection autofillFields,
|
||||||
|
IDictionary<string, FilledAutofillFieldCollection> clientFormDataMap)
|
||||||
|
{
|
||||||
|
var responseBuilder = new FillResponse.Builder();
|
||||||
|
if(clientFormDataMap != null)
|
||||||
|
{
|
||||||
|
foreach(var datasetName in clientFormDataMap.Keys)
|
||||||
|
{
|
||||||
|
if(clientFormDataMap.ContainsKey(datasetName))
|
||||||
|
{
|
||||||
|
var dataset = NewDataset(context, autofillFields, clientFormDataMap[datasetName], datasetAuth);
|
||||||
|
if(dataset != null)
|
||||||
|
{
|
||||||
|
responseBuilder.AddDataset(dataset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(autofillFields.SaveType != SaveDataType.Generic)
|
||||||
|
{
|
||||||
|
responseBuilder.SetSaveInfo(
|
||||||
|
new SaveInfo.Builder(autofillFields.SaveType, autofillFields.AutofillIds.ToArray()).Build());
|
||||||
|
return responseBuilder.Build();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Log.d(TAG, "These fields are not meant to be saved by autofill.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] FilterForSupportedHints(string[] hints)
|
||||||
|
{
|
||||||
|
if((hints?.Length ?? 0) == 0)
|
||||||
|
{
|
||||||
|
return new string[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var filteredHints = new string[hints.Length];
|
||||||
|
var i = 0;
|
||||||
|
foreach(var hint in hints)
|
||||||
|
{
|
||||||
|
if(IsValidHint(hint))
|
||||||
|
{
|
||||||
|
filteredHints[i++] = hint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var finalFilteredHints = new string[i];
|
||||||
|
Array.Copy(filteredHints, 0, finalFilteredHints, 0, i);
|
||||||
|
return finalFilteredHints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValidHint(string hint)
|
||||||
|
{
|
||||||
|
switch(hint)
|
||||||
|
{
|
||||||
|
case View.AutofillHintCreditCardExpirationDate:
|
||||||
|
case View.AutofillHintCreditCardExpirationDay:
|
||||||
|
case View.AutofillHintCreditCardExpirationMonth:
|
||||||
|
case View.AutofillHintCreditCardExpirationYear:
|
||||||
|
case View.AutofillHintCreditCardNumber:
|
||||||
|
case View.AutofillHintCreditCardSecurityCode:
|
||||||
|
case View.AutofillHintEmailAddress:
|
||||||
|
case View.AutofillHintPhone:
|
||||||
|
case View.AutofillHintName:
|
||||||
|
case View.AutofillHintPassword:
|
||||||
|
case View.AutofillHintPostalAddress:
|
||||||
|
case View.AutofillHintPostalCode:
|
||||||
|
case View.AutofillHintUsername:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
443
src/Android/Resources/Resource.Designer.cs
generated
443
src/Android/Resources/Resource.Designer.cs
generated
|
@ -2863,8 +2863,8 @@ namespace Bit.Android
|
||||||
public partial class Id
|
public partial class Id
|
||||||
{
|
{
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b7
|
// aapt resource value: 0x7f0c00b9
|
||||||
public const int action0 = 2131493047;
|
public const int action0 = 2131493049;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0062
|
// aapt resource value: 0x7f0c0062
|
||||||
public const int action_bar = 2131492962;
|
public const int action_bar = 2131492962;
|
||||||
|
@ -2890,8 +2890,8 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c0063
|
// aapt resource value: 0x7f0c0063
|
||||||
public const int action_context_bar = 2131492963;
|
public const int action_context_bar = 2131492963;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00bb
|
// aapt resource value: 0x7f0c00bd
|
||||||
public const int action_divider = 2131493051;
|
public const int action_divider = 2131493053;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0003
|
// aapt resource value: 0x7f0c0003
|
||||||
public const int action_menu_divider = 2131492867;
|
public const int action_menu_divider = 2131492867;
|
||||||
|
@ -2935,26 +2935,26 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c004c
|
// aapt resource value: 0x7f0c004c
|
||||||
public const int buttonPanel = 2131492940;
|
public const int buttonPanel = 2131492940;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c008b
|
// aapt resource value: 0x7f0c008d
|
||||||
public const int button_add_response = 2131493003;
|
public const int button_add_response = 2131493005;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0086
|
// aapt resource value: 0x7f0c0088
|
||||||
public const int button_attachment = 2131492998;
|
public const int button_attachment = 2131493000;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0090
|
// aapt resource value: 0x7f0c0092
|
||||||
public const int button_login = 2131493008;
|
public const int button_login = 2131493010;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c008c
|
// aapt resource value: 0x7f0c008e
|
||||||
public const int button_refresh = 2131493004;
|
public const int button_refresh = 2131493006;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0087
|
// aapt resource value: 0x7f0c0089
|
||||||
public const int button_send = 2131492999;
|
public const int button_send = 2131493001;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0094
|
// aapt resource value: 0x7f0c0096
|
||||||
public const int button_update = 2131493012;
|
public const int button_update = 2131493014;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b8
|
// aapt resource value: 0x7f0c00ba
|
||||||
public const int cancel_action = 2131493048;
|
public const int cancel_action = 2131493050;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0033
|
// aapt resource value: 0x7f0c0033
|
||||||
public const int center = 2131492915;
|
public const int center = 2131492915;
|
||||||
|
@ -2968,8 +2968,8 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c005a
|
// aapt resource value: 0x7f0c005a
|
||||||
public const int checkbox = 2131492954;
|
public const int checkbox = 2131492954;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00be
|
// aapt resource value: 0x7f0c00c0
|
||||||
public const int chronometer = 2131493054;
|
public const int chronometer = 2131493056;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c003b
|
// aapt resource value: 0x7f0c003b
|
||||||
public const int clip_horizontal = 2131492923;
|
public const int clip_horizontal = 2131492923;
|
||||||
|
@ -3001,20 +3001,20 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c0048
|
// aapt resource value: 0x7f0c0048
|
||||||
public const int default_activity_button = 2131492936;
|
public const int default_activity_button = 2131492936;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0072
|
// aapt resource value: 0x7f0c0074
|
||||||
public const int design_bottom_sheet = 2131492978;
|
public const int design_bottom_sheet = 2131492980;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c007b
|
||||||
|
public const int design_menu_item_action_area = 2131492987;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c007a
|
||||||
|
public const int design_menu_item_action_area_stub = 2131492986;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0079
|
// aapt resource value: 0x7f0c0079
|
||||||
public const int design_menu_item_action_area = 2131492985;
|
public const int design_menu_item_text = 2131492985;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0078
|
// aapt resource value: 0x7f0c0078
|
||||||
public const int design_menu_item_action_area_stub = 2131492984;
|
public const int design_navigation_view = 2131492984;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0077
|
|
||||||
public const int design_menu_item_text = 2131492983;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0076
|
|
||||||
public const int design_navigation_view = 2131492982;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0017
|
// aapt resource value: 0x7f0c0017
|
||||||
public const int disableHome = 2131492887;
|
public const int disableHome = 2131492887;
|
||||||
|
@ -3052,17 +3052,17 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c0036
|
// aapt resource value: 0x7f0c0036
|
||||||
public const int fill_vertical = 2131492918;
|
public const int fill_vertical = 2131492918;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c007e
|
||||||
|
public const int fingerprint_btnCancel = 2131492990;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c007f
|
||||||
|
public const int fingerprint_btnFallback = 2131492991;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c007c
|
// aapt resource value: 0x7f0c007c
|
||||||
public const int fingerprint_btnCancel = 2131492988;
|
public const int fingerprint_imgFingerprint = 2131492988;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c007d
|
// aapt resource value: 0x7f0c007d
|
||||||
public const int fingerprint_btnFallback = 2131492989;
|
public const int fingerprint_txtReason = 2131492989;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c007a
|
|
||||||
public const int fingerprint_imgFingerprint = 2131492986;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c007b
|
|
||||||
public const int fingerprint_txtReason = 2131492987;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0040
|
// aapt resource value: 0x7f0c0040
|
||||||
public const int @fixed = 2131492928;
|
public const int @fixed = 2131492928;
|
||||||
|
@ -3088,44 +3088,44 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c00c2
|
// aapt resource value: 0x7f0c00c2
|
||||||
public const int info = 2131493058;
|
public const int info = 2131493058;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0082
|
|
||||||
public const int input_email = 2131492994;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0084
|
// aapt resource value: 0x7f0c0084
|
||||||
public const int input_message = 2131492996;
|
public const int input_email = 2131492996;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0081
|
// aapt resource value: 0x7f0c0086
|
||||||
public const int input_name = 2131492993;
|
public const int input_message = 2131492998;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c008f
|
|
||||||
public const int input_password = 2131493007;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0083
|
// aapt resource value: 0x7f0c0083
|
||||||
public const int input_subject = 2131492995;
|
public const int input_name = 2131492995;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c0091
|
||||||
|
public const int input_password = 2131493009;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c0085
|
||||||
|
public const int input_subject = 2131492997;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0000
|
// aapt resource value: 0x7f0c0000
|
||||||
public const int item_touch_helper_previous_elevation = 2131492864;
|
public const int item_touch_helper_previous_elevation = 2131492864;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0096
|
|
||||||
public const int label_author = 2131493014;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0097
|
|
||||||
public const int label_date = 2131493015;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0089
|
|
||||||
public const int label_last_updated = 2131493001;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c007e
|
|
||||||
public const int label_message = 2131492990;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0098
|
// aapt resource value: 0x7f0c0098
|
||||||
public const int label_text = 2131493016;
|
public const int label_author = 2131493016;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0092
|
// aapt resource value: 0x7f0c0099
|
||||||
public const int label_title = 2131493010;
|
public const int label_date = 2131493017;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0093
|
// aapt resource value: 0x7f0c008b
|
||||||
public const int label_version = 2131493011;
|
public const int label_last_updated = 2131493003;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c0080
|
||||||
|
public const int label_message = 2131492992;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c009a
|
||||||
|
public const int label_text = 2131493018;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c0094
|
||||||
|
public const int label_title = 2131493012;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c0095
|
||||||
|
public const int label_version = 2131493013;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0037
|
// aapt resource value: 0x7f0c0037
|
||||||
public const int left = 2131492919;
|
public const int left = 2131492919;
|
||||||
|
@ -3133,35 +3133,35 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c0013
|
// aapt resource value: 0x7f0c0013
|
||||||
public const int light = 2131492883;
|
public const int light = 2131492883;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00bc
|
// aapt resource value: 0x7f0c00be
|
||||||
public const int line1 = 2131493052;
|
public const int line1 = 2131493054;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00c0
|
// aapt resource value: 0x7f0c00c1
|
||||||
public const int line3 = 2131493056;
|
public const int line3 = 2131493057;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0014
|
// aapt resource value: 0x7f0c0014
|
||||||
public const int listMode = 2131492884;
|
public const int listMode = 2131492884;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0099
|
// aapt resource value: 0x7f0c009b
|
||||||
public const int list_attachments = 2131493017;
|
public const int list_attachments = 2131493019;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c008d
|
// aapt resource value: 0x7f0c008f
|
||||||
public const int list_feedback_messages = 2131493005;
|
public const int list_feedback_messages = 2131493007;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0049
|
// aapt resource value: 0x7f0c0049
|
||||||
public const int list_item = 2131492937;
|
public const int list_item = 2131492937;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c009e
|
||||||
|
public const int loadingImage = 2131493022;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c009c
|
// aapt resource value: 0x7f0c009c
|
||||||
public const int loadingImage = 2131493020;
|
public const int loadingProgressBar = 2131493020;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c009a
|
// aapt resource value: 0x7f0c009f
|
||||||
public const int loadingProgressBar = 2131493018;
|
public const int loadingProgressWheel = 2131493023;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c009d
|
// aapt resource value: 0x7f0c00bc
|
||||||
public const int loadingProgressWheel = 2131493021;
|
public const int media_actions = 2131493052;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00ba
|
|
||||||
public const int media_actions = 2131493050;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0025
|
// aapt resource value: 0x7f0c0025
|
||||||
public const int middle = 2131492901;
|
public const int middle = 2131492901;
|
||||||
|
@ -3169,83 +3169,83 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c003f
|
// aapt resource value: 0x7f0c003f
|
||||||
public const int mini = 2131492927;
|
public const int mini = 2131492927;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a9
|
// aapt resource value: 0x7f0c00ab
|
||||||
public const int mr_art = 2131493033;
|
public const int mr_art = 2131493035;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c009e
|
|
||||||
public const int mr_chooser_list = 2131493022;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a1
|
|
||||||
public const int mr_chooser_route_desc = 2131493025;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c009f
|
|
||||||
public const int mr_chooser_route_icon = 2131493023;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a0
|
// aapt resource value: 0x7f0c00a0
|
||||||
public const int mr_chooser_route_name = 2131493024;
|
public const int mr_chooser_list = 2131493024;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a6
|
|
||||||
public const int mr_close = 2131493030;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00ac
|
|
||||||
public const int mr_control_divider = 2131493036;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b2
|
|
||||||
public const int mr_control_play_pause = 2131493042;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b5
|
|
||||||
public const int mr_control_subtitle = 2131493045;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b4
|
|
||||||
public const int mr_control_title = 2131493044;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b3
|
|
||||||
public const int mr_control_title_container = 2131493043;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a7
|
|
||||||
public const int mr_custom_control = 2131493031;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a8
|
|
||||||
public const int mr_default_control = 2131493032;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a3
|
// aapt resource value: 0x7f0c00a3
|
||||||
public const int mr_dialog_area = 2131493027;
|
public const int mr_chooser_route_desc = 2131493027;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00a1
|
||||||
|
public const int mr_chooser_route_icon = 2131493025;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a2
|
// aapt resource value: 0x7f0c00a2
|
||||||
public const int mr_expandable_area = 2131493026;
|
public const int mr_chooser_route_name = 2131493026;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b6
|
// aapt resource value: 0x7f0c00a8
|
||||||
public const int mr_group_expand_collapse = 2131493046;
|
public const int mr_close = 2131493032;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00aa
|
|
||||||
public const int mr_media_main_control = 2131493034;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a5
|
|
||||||
public const int mr_name = 2131493029;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00ab
|
|
||||||
public const int mr_playback_control = 2131493035;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00a4
|
|
||||||
public const int mr_title_bar = 2131493028;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00ad
|
|
||||||
public const int mr_volume_control = 2131493037;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00ae
|
// aapt resource value: 0x7f0c00ae
|
||||||
public const int mr_volume_group_list = 2131493038;
|
public const int mr_control_divider = 2131493038;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00b4
|
||||||
|
public const int mr_control_play_pause = 2131493044;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00b7
|
||||||
|
public const int mr_control_subtitle = 2131493047;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00b6
|
||||||
|
public const int mr_control_title = 2131493046;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00b5
|
||||||
|
public const int mr_control_title_container = 2131493045;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00a9
|
||||||
|
public const int mr_custom_control = 2131493033;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00aa
|
||||||
|
public const int mr_default_control = 2131493034;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00a5
|
||||||
|
public const int mr_dialog_area = 2131493029;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00a4
|
||||||
|
public const int mr_expandable_area = 2131493028;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00b8
|
||||||
|
public const int mr_group_expand_collapse = 2131493048;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00ac
|
||||||
|
public const int mr_media_main_control = 2131493036;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00a7
|
||||||
|
public const int mr_name = 2131493031;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00ad
|
||||||
|
public const int mr_playback_control = 2131493037;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00a6
|
||||||
|
public const int mr_title_bar = 2131493030;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00af
|
||||||
|
public const int mr_volume_control = 2131493039;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b0
|
// aapt resource value: 0x7f0c00b0
|
||||||
public const int mr_volume_item_icon = 2131493040;
|
public const int mr_volume_group_list = 2131493040;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b1
|
// aapt resource value: 0x7f0c00b2
|
||||||
public const int mr_volume_slider = 2131493041;
|
public const int mr_volume_item_icon = 2131493042;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c00b3
|
||||||
|
public const int mr_volume_slider = 2131493043;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c001e
|
// aapt resource value: 0x7f0c001e
|
||||||
public const int multiply = 2131492894;
|
public const int multiply = 2131492894;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0075
|
// aapt resource value: 0x7f0c0077
|
||||||
public const int navigation_header_container = 2131492981;
|
public const int navigation_header_container = 2131492983;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0029
|
// aapt resource value: 0x7f0c0029
|
||||||
public const int never = 2131492905;
|
public const int never = 2131492905;
|
||||||
|
@ -3343,11 +3343,11 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c00c4
|
// aapt resource value: 0x7f0c00c4
|
||||||
public const int sliding_tabs = 2131493060;
|
public const int sliding_tabs = 2131493060;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0074
|
// aapt resource value: 0x7f0c0076
|
||||||
public const int snackbar_action = 2131492980;
|
public const int snackbar_action = 2131492982;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0073
|
// aapt resource value: 0x7f0c0075
|
||||||
public const int snackbar_text = 2131492979;
|
public const int snackbar_text = 2131492981;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c002f
|
// aapt resource value: 0x7f0c002f
|
||||||
public const int snap = 2131492911;
|
public const int snap = 2131492911;
|
||||||
|
@ -3373,8 +3373,8 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c0039
|
// aapt resource value: 0x7f0c0039
|
||||||
public const int start = 2131492921;
|
public const int start = 2131492921;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00b9
|
// aapt resource value: 0x7f0c00bb
|
||||||
public const int status_bar_latest_event_content = 2131493049;
|
public const int status_bar_latest_event_content = 2131493051;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c006d
|
// aapt resource value: 0x7f0c006d
|
||||||
public const int submit_area = 2131492973;
|
public const int submit_area = 2131492973;
|
||||||
|
@ -3382,23 +3382,23 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c0016
|
// aapt resource value: 0x7f0c0016
|
||||||
public const int tabMode = 2131492886;
|
public const int tabMode = 2131492886;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00c1
|
// aapt resource value: 0x7f0c0071
|
||||||
public const int text = 2131493057;
|
public const int text = 2131492977;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00bf
|
// aapt resource value: 0x7f0c0072
|
||||||
public const int text2 = 2131493055;
|
public const int text2 = 2131492978;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0055
|
// aapt resource value: 0x7f0c0055
|
||||||
public const int textSpacerNoButtons = 2131492949;
|
public const int textSpacerNoButtons = 2131492949;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c009b
|
// aapt resource value: 0x7f0c009d
|
||||||
public const int textViewStatus = 2131493019;
|
public const int textViewStatus = 2131493021;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c008e
|
// aapt resource value: 0x7f0c0090
|
||||||
public const int text_headline = 2131493006;
|
public const int text_headline = 2131493008;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00bd
|
// aapt resource value: 0x7f0c00bf
|
||||||
public const int time = 2131493053;
|
public const int time = 2131493055;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c004b
|
// aapt resource value: 0x7f0c004b
|
||||||
public const int title = 2131492939;
|
public const int title = 2131492939;
|
||||||
|
@ -3415,8 +3415,8 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c004f
|
// aapt resource value: 0x7f0c004f
|
||||||
public const int topPanel = 2131492943;
|
public const int topPanel = 2131492943;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0071
|
// aapt resource value: 0x7f0c0073
|
||||||
public const int touch_outside = 2131492977;
|
public const int touch_outside = 2131492979;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0009
|
// aapt resource value: 0x7f0c0009
|
||||||
public const int up = 2131492873;
|
public const int up = 2131492873;
|
||||||
|
@ -3424,17 +3424,17 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c001c
|
// aapt resource value: 0x7f0c001c
|
||||||
public const int useLogo = 2131492892;
|
public const int useLogo = 2131492892;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0091
|
// aapt resource value: 0x7f0c0093
|
||||||
public const int view_header = 2131493009;
|
public const int view_header = 2131493011;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c000a
|
// aapt resource value: 0x7f0c000a
|
||||||
public const int view_offset_helper = 2131492874;
|
public const int view_offset_helper = 2131492874;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c00af
|
// aapt resource value: 0x7f0c00b1
|
||||||
public const int volume_item_container = 2131493039;
|
public const int volume_item_container = 2131493041;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0095
|
// aapt resource value: 0x7f0c0097
|
||||||
public const int web_update_details = 2131493013;
|
public const int web_update_details = 2131493015;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0010
|
// aapt resource value: 0x7f0c0010
|
||||||
public const int wide = 2131492880;
|
public const int wide = 2131492880;
|
||||||
|
@ -3445,20 +3445,20 @@ namespace Bit.Android
|
||||||
// aapt resource value: 0x7f0c001d
|
// aapt resource value: 0x7f0c001d
|
||||||
public const int wrap_content = 2131492893;
|
public const int wrap_content = 2131492893;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0085
|
// aapt resource value: 0x7f0c0087
|
||||||
public const int wrapper_attachments = 2131492997;
|
public const int wrapper_attachments = 2131492999;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0080
|
// aapt resource value: 0x7f0c0082
|
||||||
public const int wrapper_feedback = 2131492992;
|
public const int wrapper_feedback = 2131492994;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c007f
|
// aapt resource value: 0x7f0c0081
|
||||||
public const int wrapper_feedback_scroll = 2131492991;
|
public const int wrapper_feedback_scroll = 2131492993;
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c0088
|
|
||||||
public const int wrapper_messages = 2131493000;
|
|
||||||
|
|
||||||
// aapt resource value: 0x7f0c008a
|
// aapt resource value: 0x7f0c008a
|
||||||
public const int wrapper_messages_buttons = 2131493002;
|
public const int wrapper_messages = 2131493002;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f0c008c
|
||||||
|
public const int wrapper_messages_buttons = 2131493004;
|
||||||
|
|
||||||
static Id()
|
static Id()
|
||||||
{
|
{
|
||||||
|
@ -3614,136 +3614,139 @@ namespace Bit.Android
|
||||||
public const int abc_select_dialog_material = 2130903064;
|
public const int abc_select_dialog_material = 2130903064;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030019
|
// aapt resource value: 0x7f030019
|
||||||
public const int design_bottom_sheet_dialog = 2130903065;
|
public const int autofill_listitem = 2130903065;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03001a
|
// aapt resource value: 0x7f03001a
|
||||||
public const int design_layout_snackbar = 2130903066;
|
public const int design_bottom_sheet_dialog = 2130903066;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03001b
|
// aapt resource value: 0x7f03001b
|
||||||
public const int design_layout_snackbar_include = 2130903067;
|
public const int design_layout_snackbar = 2130903067;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03001c
|
// aapt resource value: 0x7f03001c
|
||||||
public const int design_layout_tab_icon = 2130903068;
|
public const int design_layout_snackbar_include = 2130903068;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03001d
|
// aapt resource value: 0x7f03001d
|
||||||
public const int design_layout_tab_text = 2130903069;
|
public const int design_layout_tab_icon = 2130903069;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03001e
|
// aapt resource value: 0x7f03001e
|
||||||
public const int design_menu_item_action_area = 2130903070;
|
public const int design_layout_tab_text = 2130903070;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03001f
|
// aapt resource value: 0x7f03001f
|
||||||
public const int design_navigation_item = 2130903071;
|
public const int design_menu_item_action_area = 2130903071;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030020
|
// aapt resource value: 0x7f030020
|
||||||
public const int design_navigation_item_header = 2130903072;
|
public const int design_navigation_item = 2130903072;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030021
|
// aapt resource value: 0x7f030021
|
||||||
public const int design_navigation_item_separator = 2130903073;
|
public const int design_navigation_item_header = 2130903073;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030022
|
// aapt resource value: 0x7f030022
|
||||||
public const int design_navigation_item_subheader = 2130903074;
|
public const int design_navigation_item_separator = 2130903074;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030023
|
// aapt resource value: 0x7f030023
|
||||||
public const int design_navigation_menu = 2130903075;
|
public const int design_navigation_item_subheader = 2130903075;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030024
|
// aapt resource value: 0x7f030024
|
||||||
public const int design_navigation_menu_item = 2130903076;
|
public const int design_navigation_menu = 2130903076;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030025
|
// aapt resource value: 0x7f030025
|
||||||
public const int FingerprintDialog = 2130903077;
|
public const int design_navigation_menu_item = 2130903077;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030026
|
// aapt resource value: 0x7f030026
|
||||||
public const int hockeyapp_activity_expiry_info = 2130903078;
|
public const int FingerprintDialog = 2130903078;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030027
|
// aapt resource value: 0x7f030027
|
||||||
public const int hockeyapp_activity_feedback = 2130903079;
|
public const int hockeyapp_activity_expiry_info = 2130903079;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030028
|
// aapt resource value: 0x7f030028
|
||||||
public const int hockeyapp_activity_login = 2130903080;
|
public const int hockeyapp_activity_feedback = 2130903080;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030029
|
// aapt resource value: 0x7f030029
|
||||||
public const int hockeyapp_activity_update = 2130903081;
|
public const int hockeyapp_activity_login = 2130903081;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03002a
|
// aapt resource value: 0x7f03002a
|
||||||
public const int hockeyapp_fragment_update = 2130903082;
|
public const int hockeyapp_activity_update = 2130903082;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03002b
|
// aapt resource value: 0x7f03002b
|
||||||
public const int hockeyapp_view_feedback_message = 2130903083;
|
public const int hockeyapp_fragment_update = 2130903083;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03002c
|
// aapt resource value: 0x7f03002c
|
||||||
public const int loading = 2130903084;
|
public const int hockeyapp_view_feedback_message = 2130903084;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03002d
|
// aapt resource value: 0x7f03002d
|
||||||
public const int loadingimage = 2130903085;
|
public const int loading = 2130903085;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03002e
|
// aapt resource value: 0x7f03002e
|
||||||
public const int loadingprogress = 2130903086;
|
public const int loadingimage = 2130903086;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03002f
|
// aapt resource value: 0x7f03002f
|
||||||
public const int mr_chooser_dialog = 2130903087;
|
public const int loadingprogress = 2130903087;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030030
|
// aapt resource value: 0x7f030030
|
||||||
public const int mr_chooser_list_item = 2130903088;
|
public const int mr_chooser_dialog = 2130903088;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030031
|
// aapt resource value: 0x7f030031
|
||||||
public const int mr_controller_material_dialog_b = 2130903089;
|
public const int mr_chooser_list_item = 2130903089;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030032
|
// aapt resource value: 0x7f030032
|
||||||
public const int mr_controller_volume_item = 2130903090;
|
public const int mr_controller_material_dialog_b = 2130903090;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030033
|
// aapt resource value: 0x7f030033
|
||||||
public const int mr_playback_control = 2130903091;
|
public const int mr_controller_volume_item = 2130903091;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030034
|
// aapt resource value: 0x7f030034
|
||||||
public const int mr_volume_control = 2130903092;
|
public const int mr_playback_control = 2130903092;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030035
|
// aapt resource value: 0x7f030035
|
||||||
public const int notification_media_action = 2130903093;
|
public const int mr_volume_control = 2130903093;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030036
|
// aapt resource value: 0x7f030036
|
||||||
public const int notification_media_cancel_action = 2130903094;
|
public const int notification_media_action = 2130903094;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030037
|
// aapt resource value: 0x7f030037
|
||||||
public const int notification_template_big_media = 2130903095;
|
public const int notification_media_cancel_action = 2130903095;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030038
|
// aapt resource value: 0x7f030038
|
||||||
public const int notification_template_big_media_narrow = 2130903096;
|
public const int notification_template_big_media = 2130903096;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030039
|
// aapt resource value: 0x7f030039
|
||||||
public const int notification_template_lines = 2130903097;
|
public const int notification_template_big_media_narrow = 2130903097;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03003a
|
// aapt resource value: 0x7f03003a
|
||||||
public const int notification_template_media = 2130903098;
|
public const int notification_template_lines = 2130903098;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03003b
|
// aapt resource value: 0x7f03003b
|
||||||
public const int notification_template_part_chronometer = 2130903099;
|
public const int notification_template_media = 2130903099;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03003c
|
// aapt resource value: 0x7f03003c
|
||||||
public const int notification_template_part_time = 2130903100;
|
public const int notification_template_part_chronometer = 2130903100;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03003d
|
// aapt resource value: 0x7f03003d
|
||||||
public const int select_dialog_item_material = 2130903101;
|
public const int notification_template_part_time = 2130903101;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03003e
|
// aapt resource value: 0x7f03003e
|
||||||
public const int select_dialog_multichoice_material = 2130903102;
|
public const int select_dialog_item_material = 2130903102;
|
||||||
|
|
||||||
// aapt resource value: 0x7f03003f
|
// aapt resource value: 0x7f03003f
|
||||||
public const int select_dialog_singlechoice_material = 2130903103;
|
public const int select_dialog_multichoice_material = 2130903103;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030040
|
// aapt resource value: 0x7f030040
|
||||||
public const int support_simple_spinner_dropdown_item = 2130903104;
|
public const int select_dialog_singlechoice_material = 2130903104;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030041
|
// aapt resource value: 0x7f030041
|
||||||
public const int tabs = 2130903105;
|
public const int support_simple_spinner_dropdown_item = 2130903105;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030042
|
// aapt resource value: 0x7f030042
|
||||||
public const int toolbar = 2130903106;
|
public const int tabs = 2130903106;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030043
|
// aapt resource value: 0x7f030043
|
||||||
public const int zxingscanneractivitylayout = 2130903107;
|
public const int toolbar = 2130903107;
|
||||||
|
|
||||||
// aapt resource value: 0x7f030044
|
// aapt resource value: 0x7f030044
|
||||||
public const int zxingscannerfragmentlayout = 2130903108;
|
public const int zxingscanneractivitylayout = 2130903108;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f030045
|
||||||
|
public const int zxingscannerfragmentlayout = 2130903109;
|
||||||
|
|
||||||
static Layout()
|
static Layout()
|
||||||
{
|
{
|
||||||
|
|
34
src/Android/Resources/layout/autofill_listitem.axml
Normal file
34
src/Android/Resources/layout/autofill_listitem.axml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:background="@color/lightgray"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:src="@drawable/user" />
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:text="Name" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:text="Username" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
Loading…
Reference in a new issue