From 849ec6fa8f06536bc34f1da56ebee49ecb981534 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 14 Nov 2017 16:31:03 -0500 Subject: [PATCH] add old autofill implementation for reference. --- src/Android/Android.csproj | 4 + src/Android/AutofillFrameworkService_OLD.cs | 630 ++++++++++++++++++ src/Android/Resources/Resource.Designer.cs | 443 ++++++------ .../Resources/layout/autofill_listitem.axml | 34 + 4 files changed, 891 insertions(+), 220 deletions(-) create mode 100644 src/Android/AutofillFrameworkService_OLD.cs create mode 100644 src/Android/Resources/layout/autofill_listitem.axml diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj index d5d936985..e0358a9a6 100644 --- a/src/Android/Android.csproj +++ b/src/Android/Android.csproj @@ -287,6 +287,7 @@ + @@ -342,6 +343,9 @@ AndroidResource + + AndroidResource + diff --git a/src/Android/AutofillFrameworkService_OLD.cs b/src/Android/AutofillFrameworkService_OLD.cs new file mode 100644 index 000000000..c12059827 --- /dev/null +++ b/src/Android/AutofillFrameworkService_OLD.cs @@ -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 + { + { 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 + { + { View.AutofillHintUsername, username2 }, + { View.AutofillHintPassword, password2 } + }; + var col2 = new FilledAutofillFieldCollection("Login 2 Name", login2); + + var clientFormDataMap = new Dictionary + { + { "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 Ids { get; private set; } = new List(); + public List AutofillIds { get; private set; } = new List(); + public SaveDataType SaveType { get; private set; } = SaveDataType.Generic; + public List AutofillHints { get; private set; } = new List(); + public List FocusedAutofillHints { get; private set; } = new List(); + public List Feilds { get; private set; } + public IDictionary IdToFieldMap { get; private set; } = + new Dictionary(); + public IDictionary> AutofillHintsToFieldsMap { get; private set; } = + new Dictionary>(); + + 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()); + } + + AutofillHintsToFieldsMap[hint].Add(data); + } + } + } + } + + public class AutofillFieldMetadata + { + private List _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(); + } + + public SaveDataType SaveType { get; set; } = SaveDataType.Generic; + public List 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()) + { + } + + public FilledAutofillFieldCollection(string datasetName, IDictionary hintMap) + { + HintMap = hintMap; + DatasetName = datasetName; + } + + public IDictionary 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 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 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; + } + } + } +} \ No newline at end of file diff --git a/src/Android/Resources/Resource.Designer.cs b/src/Android/Resources/Resource.Designer.cs index 2b082bb55..f9f5f4a6f 100644 --- a/src/Android/Resources/Resource.Designer.cs +++ b/src/Android/Resources/Resource.Designer.cs @@ -2863,8 +2863,8 @@ namespace Bit.Android public partial class Id { - // aapt resource value: 0x7f0c00b7 - public const int action0 = 2131493047; + // aapt resource value: 0x7f0c00b9 + public const int action0 = 2131493049; // aapt resource value: 0x7f0c0062 public const int action_bar = 2131492962; @@ -2890,8 +2890,8 @@ namespace Bit.Android // aapt resource value: 0x7f0c0063 public const int action_context_bar = 2131492963; - // aapt resource value: 0x7f0c00bb - public const int action_divider = 2131493051; + // aapt resource value: 0x7f0c00bd + public const int action_divider = 2131493053; // aapt resource value: 0x7f0c0003 public const int action_menu_divider = 2131492867; @@ -2935,26 +2935,26 @@ namespace Bit.Android // aapt resource value: 0x7f0c004c public const int buttonPanel = 2131492940; - // aapt resource value: 0x7f0c008b - public const int button_add_response = 2131493003; + // aapt resource value: 0x7f0c008d + public const int button_add_response = 2131493005; - // aapt resource value: 0x7f0c0086 - public const int button_attachment = 2131492998; + // aapt resource value: 0x7f0c0088 + public const int button_attachment = 2131493000; - // aapt resource value: 0x7f0c0090 - public const int button_login = 2131493008; + // aapt resource value: 0x7f0c0092 + public const int button_login = 2131493010; - // aapt resource value: 0x7f0c008c - public const int button_refresh = 2131493004; + // aapt resource value: 0x7f0c008e + public const int button_refresh = 2131493006; - // aapt resource value: 0x7f0c0087 - public const int button_send = 2131492999; + // aapt resource value: 0x7f0c0089 + public const int button_send = 2131493001; - // aapt resource value: 0x7f0c0094 - public const int button_update = 2131493012; + // aapt resource value: 0x7f0c0096 + public const int button_update = 2131493014; - // aapt resource value: 0x7f0c00b8 - public const int cancel_action = 2131493048; + // aapt resource value: 0x7f0c00ba + public const int cancel_action = 2131493050; // aapt resource value: 0x7f0c0033 public const int center = 2131492915; @@ -2968,8 +2968,8 @@ namespace Bit.Android // aapt resource value: 0x7f0c005a public const int checkbox = 2131492954; - // aapt resource value: 0x7f0c00be - public const int chronometer = 2131493054; + // aapt resource value: 0x7f0c00c0 + public const int chronometer = 2131493056; // aapt resource value: 0x7f0c003b public const int clip_horizontal = 2131492923; @@ -3001,20 +3001,20 @@ namespace Bit.Android // aapt resource value: 0x7f0c0048 public const int default_activity_button = 2131492936; - // aapt resource value: 0x7f0c0072 - public const int design_bottom_sheet = 2131492978; + // aapt resource value: 0x7f0c0074 + 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 - public const int design_menu_item_action_area = 2131492985; + public const int design_menu_item_text = 2131492985; // aapt resource value: 0x7f0c0078 - public const int design_menu_item_action_area_stub = 2131492984; - - // aapt resource value: 0x7f0c0077 - public const int design_menu_item_text = 2131492983; - - // aapt resource value: 0x7f0c0076 - public const int design_navigation_view = 2131492982; + public const int design_navigation_view = 2131492984; // aapt resource value: 0x7f0c0017 public const int disableHome = 2131492887; @@ -3052,17 +3052,17 @@ namespace Bit.Android // aapt resource value: 0x7f0c0036 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 - public const int fingerprint_btnCancel = 2131492988; + public const int fingerprint_imgFingerprint = 2131492988; // aapt resource value: 0x7f0c007d - public const int fingerprint_btnFallback = 2131492989; - - // aapt resource value: 0x7f0c007a - public const int fingerprint_imgFingerprint = 2131492986; - - // aapt resource value: 0x7f0c007b - public const int fingerprint_txtReason = 2131492987; + public const int fingerprint_txtReason = 2131492989; // aapt resource value: 0x7f0c0040 public const int @fixed = 2131492928; @@ -3088,44 +3088,44 @@ namespace Bit.Android // aapt resource value: 0x7f0c00c2 public const int info = 2131493058; - // aapt resource value: 0x7f0c0082 - public const int input_email = 2131492994; - // aapt resource value: 0x7f0c0084 - public const int input_message = 2131492996; + public const int input_email = 2131492996; - // aapt resource value: 0x7f0c0081 - public const int input_name = 2131492993; - - // aapt resource value: 0x7f0c008f - public const int input_password = 2131493007; + // aapt resource value: 0x7f0c0086 + public const int input_message = 2131492998; // 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 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 - public const int label_text = 2131493016; + public const int label_author = 2131493016; - // aapt resource value: 0x7f0c0092 - public const int label_title = 2131493010; + // aapt resource value: 0x7f0c0099 + public const int label_date = 2131493017; - // aapt resource value: 0x7f0c0093 - public const int label_version = 2131493011; + // aapt resource value: 0x7f0c008b + 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 public const int left = 2131492919; @@ -3133,35 +3133,35 @@ namespace Bit.Android // aapt resource value: 0x7f0c0013 public const int light = 2131492883; - // aapt resource value: 0x7f0c00bc - public const int line1 = 2131493052; + // aapt resource value: 0x7f0c00be + public const int line1 = 2131493054; - // aapt resource value: 0x7f0c00c0 - public const int line3 = 2131493056; + // aapt resource value: 0x7f0c00c1 + public const int line3 = 2131493057; // aapt resource value: 0x7f0c0014 public const int listMode = 2131492884; - // aapt resource value: 0x7f0c0099 - public const int list_attachments = 2131493017; + // aapt resource value: 0x7f0c009b + public const int list_attachments = 2131493019; - // aapt resource value: 0x7f0c008d - public const int list_feedback_messages = 2131493005; + // aapt resource value: 0x7f0c008f + public const int list_feedback_messages = 2131493007; // aapt resource value: 0x7f0c0049 public const int list_item = 2131492937; + // aapt resource value: 0x7f0c009e + public const int loadingImage = 2131493022; + // aapt resource value: 0x7f0c009c - public const int loadingImage = 2131493020; + public const int loadingProgressBar = 2131493020; - // aapt resource value: 0x7f0c009a - public const int loadingProgressBar = 2131493018; + // aapt resource value: 0x7f0c009f + public const int loadingProgressWheel = 2131493023; - // aapt resource value: 0x7f0c009d - public const int loadingProgressWheel = 2131493021; - - // aapt resource value: 0x7f0c00ba - public const int media_actions = 2131493050; + // aapt resource value: 0x7f0c00bc + public const int media_actions = 2131493052; // aapt resource value: 0x7f0c0025 public const int middle = 2131492901; @@ -3169,83 +3169,83 @@ namespace Bit.Android // aapt resource value: 0x7f0c003f public const int mini = 2131492927; - // aapt resource value: 0x7f0c00a9 - public const int mr_art = 2131493033; - - // 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: 0x7f0c00ab + public const int mr_art = 2131493035; // aapt resource value: 0x7f0c00a0 - public const int mr_chooser_route_name = 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; + public const int mr_chooser_list = 2131493024; // 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 - public const int mr_expandable_area = 2131493026; + public const int mr_chooser_route_name = 2131493026; - // aapt resource value: 0x7f0c00b6 - public const int mr_group_expand_collapse = 2131493046; - - // 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: 0x7f0c00a8 + public const int mr_close = 2131493032; // 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 - public const int mr_volume_item_icon = 2131493040; + public const int mr_volume_group_list = 2131493040; - // aapt resource value: 0x7f0c00b1 - public const int mr_volume_slider = 2131493041; + // aapt resource value: 0x7f0c00b2 + public const int mr_volume_item_icon = 2131493042; + + // aapt resource value: 0x7f0c00b3 + public const int mr_volume_slider = 2131493043; // aapt resource value: 0x7f0c001e public const int multiply = 2131492894; - // aapt resource value: 0x7f0c0075 - public const int navigation_header_container = 2131492981; + // aapt resource value: 0x7f0c0077 + public const int navigation_header_container = 2131492983; // aapt resource value: 0x7f0c0029 public const int never = 2131492905; @@ -3343,11 +3343,11 @@ namespace Bit.Android // aapt resource value: 0x7f0c00c4 public const int sliding_tabs = 2131493060; - // aapt resource value: 0x7f0c0074 - public const int snackbar_action = 2131492980; + // aapt resource value: 0x7f0c0076 + public const int snackbar_action = 2131492982; - // aapt resource value: 0x7f0c0073 - public const int snackbar_text = 2131492979; + // aapt resource value: 0x7f0c0075 + public const int snackbar_text = 2131492981; // aapt resource value: 0x7f0c002f public const int snap = 2131492911; @@ -3373,8 +3373,8 @@ namespace Bit.Android // aapt resource value: 0x7f0c0039 public const int start = 2131492921; - // aapt resource value: 0x7f0c00b9 - public const int status_bar_latest_event_content = 2131493049; + // aapt resource value: 0x7f0c00bb + public const int status_bar_latest_event_content = 2131493051; // aapt resource value: 0x7f0c006d public const int submit_area = 2131492973; @@ -3382,23 +3382,23 @@ namespace Bit.Android // aapt resource value: 0x7f0c0016 public const int tabMode = 2131492886; - // aapt resource value: 0x7f0c00c1 - public const int text = 2131493057; + // aapt resource value: 0x7f0c0071 + public const int text = 2131492977; - // aapt resource value: 0x7f0c00bf - public const int text2 = 2131493055; + // aapt resource value: 0x7f0c0072 + public const int text2 = 2131492978; // aapt resource value: 0x7f0c0055 public const int textSpacerNoButtons = 2131492949; - // aapt resource value: 0x7f0c009b - public const int textViewStatus = 2131493019; + // aapt resource value: 0x7f0c009d + public const int textViewStatus = 2131493021; - // aapt resource value: 0x7f0c008e - public const int text_headline = 2131493006; + // aapt resource value: 0x7f0c0090 + public const int text_headline = 2131493008; - // aapt resource value: 0x7f0c00bd - public const int time = 2131493053; + // aapt resource value: 0x7f0c00bf + public const int time = 2131493055; // aapt resource value: 0x7f0c004b public const int title = 2131492939; @@ -3415,8 +3415,8 @@ namespace Bit.Android // aapt resource value: 0x7f0c004f public const int topPanel = 2131492943; - // aapt resource value: 0x7f0c0071 - public const int touch_outside = 2131492977; + // aapt resource value: 0x7f0c0073 + public const int touch_outside = 2131492979; // aapt resource value: 0x7f0c0009 public const int up = 2131492873; @@ -3424,17 +3424,17 @@ namespace Bit.Android // aapt resource value: 0x7f0c001c public const int useLogo = 2131492892; - // aapt resource value: 0x7f0c0091 - public const int view_header = 2131493009; + // aapt resource value: 0x7f0c0093 + public const int view_header = 2131493011; // aapt resource value: 0x7f0c000a public const int view_offset_helper = 2131492874; - // aapt resource value: 0x7f0c00af - public const int volume_item_container = 2131493039; + // aapt resource value: 0x7f0c00b1 + public const int volume_item_container = 2131493041; - // aapt resource value: 0x7f0c0095 - public const int web_update_details = 2131493013; + // aapt resource value: 0x7f0c0097 + public const int web_update_details = 2131493015; // aapt resource value: 0x7f0c0010 public const int wide = 2131492880; @@ -3445,20 +3445,20 @@ namespace Bit.Android // aapt resource value: 0x7f0c001d public const int wrap_content = 2131492893; - // aapt resource value: 0x7f0c0085 - public const int wrapper_attachments = 2131492997; + // aapt resource value: 0x7f0c0087 + public const int wrapper_attachments = 2131492999; - // aapt resource value: 0x7f0c0080 - public const int wrapper_feedback = 2131492992; + // aapt resource value: 0x7f0c0082 + public const int wrapper_feedback = 2131492994; - // aapt resource value: 0x7f0c007f - public const int wrapper_feedback_scroll = 2131492991; - - // aapt resource value: 0x7f0c0088 - public const int wrapper_messages = 2131493000; + // aapt resource value: 0x7f0c0081 + public const int wrapper_feedback_scroll = 2131492993; // 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() { @@ -3614,136 +3614,139 @@ namespace Bit.Android public const int abc_select_dialog_material = 2130903064; // aapt resource value: 0x7f030019 - public const int design_bottom_sheet_dialog = 2130903065; + public const int autofill_listitem = 2130903065; // aapt resource value: 0x7f03001a - public const int design_layout_snackbar = 2130903066; + public const int design_bottom_sheet_dialog = 2130903066; // aapt resource value: 0x7f03001b - public const int design_layout_snackbar_include = 2130903067; + public const int design_layout_snackbar = 2130903067; // aapt resource value: 0x7f03001c - public const int design_layout_tab_icon = 2130903068; + public const int design_layout_snackbar_include = 2130903068; // aapt resource value: 0x7f03001d - public const int design_layout_tab_text = 2130903069; + public const int design_layout_tab_icon = 2130903069; // 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 - public const int design_navigation_item = 2130903071; + public const int design_menu_item_action_area = 2130903071; // aapt resource value: 0x7f030020 - public const int design_navigation_item_header = 2130903072; + public const int design_navigation_item = 2130903072; // aapt resource value: 0x7f030021 - public const int design_navigation_item_separator = 2130903073; + public const int design_navigation_item_header = 2130903073; // aapt resource value: 0x7f030022 - public const int design_navigation_item_subheader = 2130903074; + public const int design_navigation_item_separator = 2130903074; // aapt resource value: 0x7f030023 - public const int design_navigation_menu = 2130903075; + public const int design_navigation_item_subheader = 2130903075; // aapt resource value: 0x7f030024 - public const int design_navigation_menu_item = 2130903076; + public const int design_navigation_menu = 2130903076; // aapt resource value: 0x7f030025 - public const int FingerprintDialog = 2130903077; + public const int design_navigation_menu_item = 2130903077; // aapt resource value: 0x7f030026 - public const int hockeyapp_activity_expiry_info = 2130903078; + public const int FingerprintDialog = 2130903078; // aapt resource value: 0x7f030027 - public const int hockeyapp_activity_feedback = 2130903079; + public const int hockeyapp_activity_expiry_info = 2130903079; // aapt resource value: 0x7f030028 - public const int hockeyapp_activity_login = 2130903080; + public const int hockeyapp_activity_feedback = 2130903080; // aapt resource value: 0x7f030029 - public const int hockeyapp_activity_update = 2130903081; + public const int hockeyapp_activity_login = 2130903081; // aapt resource value: 0x7f03002a - public const int hockeyapp_fragment_update = 2130903082; + public const int hockeyapp_activity_update = 2130903082; // aapt resource value: 0x7f03002b - public const int hockeyapp_view_feedback_message = 2130903083; + public const int hockeyapp_fragment_update = 2130903083; // aapt resource value: 0x7f03002c - public const int loading = 2130903084; + public const int hockeyapp_view_feedback_message = 2130903084; // aapt resource value: 0x7f03002d - public const int loadingimage = 2130903085; + public const int loading = 2130903085; // aapt resource value: 0x7f03002e - public const int loadingprogress = 2130903086; + public const int loadingimage = 2130903086; // aapt resource value: 0x7f03002f - public const int mr_chooser_dialog = 2130903087; + public const int loadingprogress = 2130903087; // aapt resource value: 0x7f030030 - public const int mr_chooser_list_item = 2130903088; + public const int mr_chooser_dialog = 2130903088; // 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 - public const int mr_controller_volume_item = 2130903090; + public const int mr_controller_material_dialog_b = 2130903090; // aapt resource value: 0x7f030033 - public const int mr_playback_control = 2130903091; + public const int mr_controller_volume_item = 2130903091; // aapt resource value: 0x7f030034 - public const int mr_volume_control = 2130903092; + public const int mr_playback_control = 2130903092; // aapt resource value: 0x7f030035 - public const int notification_media_action = 2130903093; + public const int mr_volume_control = 2130903093; // aapt resource value: 0x7f030036 - public const int notification_media_cancel_action = 2130903094; + public const int notification_media_action = 2130903094; // aapt resource value: 0x7f030037 - public const int notification_template_big_media = 2130903095; + public const int notification_media_cancel_action = 2130903095; // 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 - public const int notification_template_lines = 2130903097; + public const int notification_template_big_media_narrow = 2130903097; // aapt resource value: 0x7f03003a - public const int notification_template_media = 2130903098; + public const int notification_template_lines = 2130903098; // aapt resource value: 0x7f03003b - public const int notification_template_part_chronometer = 2130903099; + public const int notification_template_media = 2130903099; // aapt resource value: 0x7f03003c - public const int notification_template_part_time = 2130903100; + public const int notification_template_part_chronometer = 2130903100; // aapt resource value: 0x7f03003d - public const int select_dialog_item_material = 2130903101; + public const int notification_template_part_time = 2130903101; // aapt resource value: 0x7f03003e - public const int select_dialog_multichoice_material = 2130903102; + public const int select_dialog_item_material = 2130903102; // aapt resource value: 0x7f03003f - public const int select_dialog_singlechoice_material = 2130903103; + public const int select_dialog_multichoice_material = 2130903103; // 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 - public const int tabs = 2130903105; + public const int support_simple_spinner_dropdown_item = 2130903105; // aapt resource value: 0x7f030042 - public const int toolbar = 2130903106; + public const int tabs = 2130903106; // aapt resource value: 0x7f030043 - public const int zxingscanneractivitylayout = 2130903107; + public const int toolbar = 2130903107; // 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() { diff --git a/src/Android/Resources/layout/autofill_listitem.axml b/src/Android/Resources/layout/autofill_listitem.axml new file mode 100644 index 000000000..2e1f41eaa --- /dev/null +++ b/src/Android/Resources/layout/autofill_listitem.axml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file