From 1ed1e911894d557befadda3812accf5a9e84c551 Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Thu, 28 Dec 2017 03:04:03 +0100 Subject: [PATCH] first working (but still very rudimentary) version of Oreo Autofill (#9). Not yet implemented and/or tested: partitioning, autofill fields without hints, saving, filling of other fields than username or password, package signature verification, DAL --- .../layout/autofill_service_list_item.xml | 3 +- src/keepass2android/ShareUrlResults.cs | 9 +- src/keepass2android/keepass2android.csproj | 1 + .../AutofillBase/AutofillFieldMetadata.cs | 9 +- .../AutofillFieldMetadataCollection.cs | 4 +- .../services/AutofillBase/AutofillHelper.cs | 44 +----- .../AutofillBase/AutofillHintsHelper.cs | 87 ++++++++++++ .../AutofillBase/AutofillServiceBase.cs | 23 +++- .../ChooseForAutofillActivityBase.cs | 29 ++-- .../services/AutofillBase/CommonUtil.cs | 15 +- .../services/AutofillBase/StructureParser.cs | 11 +- .../AutofillBase/model/FilledAutofillField.cs | 7 +- .../model/FilledAutofillFieldCollection.cs | 128 +++++++++++++++--- .../services/AutofillBase/model/W3cHints.cs | 118 ++++++++-------- .../Kp2aAutofill/ChooseForAutofillActivity.cs | 6 +- .../services/Kp2aAutofillIntentBuilder.cs | 4 +- 16 files changed, 336 insertions(+), 162 deletions(-) create mode 100644 src/keepass2android/services/AutofillBase/AutofillHintsHelper.cs diff --git a/src/keepass2android/Resources/layout/autofill_service_list_item.xml b/src/keepass2android/Resources/layout/autofill_service_list_item.xml index 8d06a671..b238ba41 100644 --- a/src/keepass2android/Resources/layout/autofill_service_list_item.xml +++ b/src/keepass2android/Resources/layout/autofill_service_list_item.xml @@ -16,7 +16,7 @@ (Resource.Id.list_fragment).ListAdapter = new PwGroupListAdapter(this, Group); View selectOtherEntry = FindViewById (Resource.Id.select_other_entry); - selectOtherEntry.Click += (sender, e) => { - GroupActivity.Launch (this, new SelectEntryForUrlTask(url)); + + var newTask = new SelectEntryForUrlTask(url); + if (AppTask is SelectEntryTask currentSelectTask) + newTask.ShowUserNotifications = currentSelectTask.ShowUserNotifications; + + selectOtherEntry.Click += (sender, e) => { + GroupActivity.Launch (this, newTask); }; diff --git a/src/keepass2android/keepass2android.csproj b/src/keepass2android/keepass2android.csproj index adedc61b..c3efbdbd 100644 --- a/src/keepass2android/keepass2android.csproj +++ b/src/keepass2android/keepass2android.csproj @@ -217,6 +217,7 @@ + diff --git a/src/keepass2android/services/AutofillBase/AutofillFieldMetadata.cs b/src/keepass2android/services/AutofillBase/AutofillFieldMetadata.cs index 0ba9593c..38f74458 100644 --- a/src/keepass2android/services/AutofillBase/AutofillFieldMetadata.cs +++ b/src/keepass2android/services/AutofillBase/AutofillFieldMetadata.cs @@ -28,9 +28,11 @@ namespace keepass2android.services.AutofillBase AutofillType = view.AutofillType; AutofillOptions = view.GetAutofillOptions(); Focused = view.IsFocused; - //TODO port and use AutoFillHints - SetHints(AutofillHelper.FilterForSupportedHints(view.GetAutofillHints())); - } + var supportedHints = AutofillHintsHelper.FilterForSupportedHints(view.GetAutofillHints()); + var storedHints = AutofillHintsHelper.ConvertToStoredHints(supportedHints); + SetHints(storedHints.ToArray()); + + } void SetHints(string[] value) { @@ -58,6 +60,7 @@ namespace keepass2android.services.AutofillBase void UpdateSaveTypeFromHints() { + //TODO future add savetypes for W3cHints SaveType = 0; if (AutofillHints == null) { diff --git a/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs b/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs index 8e38a148..d02434ae 100644 --- a/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs +++ b/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs @@ -40,7 +40,7 @@ namespace keepass2android.services.AutofillBase { if (!AutofillHintsToFieldsMap.ContainsKey(hint)) { - AutofillHintsToFieldsMap.Add(hint, new List()); + AutofillHintsToFieldsMap.Add(hint, new List()); } AutofillHintsToFieldsMap[hint].Add(autofillFieldMetadata); } @@ -51,7 +51,7 @@ namespace keepass2android.services.AutofillBase return AutofillIds.ToArray(); } - public List GetFieldsForHint(String hint) + public List GetFieldsForHint(String hint) { return AutofillHintsToFieldsMap[hint]; } diff --git a/src/keepass2android/services/AutofillBase/AutofillHelper.cs b/src/keepass2android/services/AutofillBase/AutofillHelper.cs index fbd42107..cc15f766 100644 --- a/src/keepass2android/services/AutofillBase/AutofillHelper.cs +++ b/src/keepass2android/services/AutofillBase/AutofillHelper.cs @@ -7,7 +7,6 @@ using Android.Views; using Android.Widget; using FilledAutofillFieldCollection = keepass2android.services.AutofillBase.model.FilledAutofillFieldCollection; -//TODO compare port namespace keepass2android.services.AutofillBase { /// @@ -93,6 +92,7 @@ namespace keepass2android.services.AutofillBase } if (autofillFields.SaveType != 0) { + //TODO implement save var autofillIds = autofillFields.GetAutofillIds(); responseBuilder.SetSaveInfo (new SaveInfo.Builder(autofillFields.SaveType, autofillIds).Build()); @@ -105,47 +105,5 @@ namespace keepass2android.services.AutofillBase } } - public static string[] FilterForSupportedHints(string[] hints) - { - var filteredHints = new string[hints.Length]; - int i = 0; - foreach (var hint in hints) - { - if (IsValidHint(hint)) - { - filteredHints[i++] = hint; - } - else - { - Log.Debug(CommonUtil.Tag, "Invalid autofill hint: " + 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; - } - } } } diff --git a/src/keepass2android/services/AutofillBase/AutofillHintsHelper.cs b/src/keepass2android/services/AutofillBase/AutofillHintsHelper.cs new file mode 100644 index 00000000..ea2c8730 --- /dev/null +++ b/src/keepass2android/services/AutofillBase/AutofillHintsHelper.cs @@ -0,0 +1,87 @@ +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.Util; +using Android.Views; +using Android.Widget; +using keepass2android.services.AutofillBase.model; + +namespace keepass2android.services.AutofillBase +{ + class AutofillHintsHelper + { + private static readonly HashSet validHints = new HashSet() + { + View.AutofillHintUsername, + View.AutofillHintPassword, + W3cHints.USERNAME, + W3cHints.CURRENT_PASSWORD, + W3cHints.NEW_PASSWORD + }; + + private static readonly Dictionary hintReplacements= new Dictionary() + { + {W3cHints.EMAIL, View.AutofillHintEmailAddress}, + {W3cHints.USERNAME, View.AutofillHintUsername}, + {W3cHints.CURRENT_PASSWORD, View.AutofillHintPassword}, + {W3cHints.NEW_PASSWORD, View.AutofillHintPassword}, + {W3cHints.CC_EXPIRATION_MONTH, View.AutofillHintCreditCardExpirationMonth }, + {W3cHints.CC_EXPIRATION_YEAR, View.AutofillHintCreditCardExpirationYear }, + {W3cHints.CC_EXPIRATION, View.AutofillHintCreditCardExpirationDate }, + {W3cHints.CC_NUMBER, View.AutofillHintCreditCardNumber }, + {W3cHints.CC_CSC, View.AutofillHintCreditCardSecurityCode }, + {W3cHints.POSTAL_CODE, View.AutofillHintPostalCode }, + + + }; + + public static bool IsValidHint(string hint) + { + return validHints.Contains(hint); + } + + + public static string[] FilterForSupportedHints(string[] hints) + { + var filteredHints = new string[hints.Length]; + int i = 0; + foreach (var hint in hints) + { + if (IsValidHint(hint)) + { + filteredHints[i++] = hint; + } + else + { + Log.Debug(CommonUtil.Tag, "Invalid autofill hint: " + hint); + } + } + var finalFilteredHints = new string[i]; + Array.Copy(filteredHints, 0, finalFilteredHints, 0, i); + return finalFilteredHints; + } + + + + public static List ConvertToStoredHints(string[] supportedHints) + { + List result = new List(); + foreach (string hint in supportedHints) + { + string storedHint = hint; + if (hintReplacements.ContainsKey(hint)) + storedHint = hintReplacements[hint]; + result.Add(storedHint); + + } + return result; + + } + } +} \ No newline at end of file diff --git a/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs b/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs index b6e5c627..7aa5be42 100644 --- a/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs +++ b/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs @@ -4,6 +4,8 @@ using Android.OS; using Android.Runtime; using Android.Service.Autofill; using Android.Util; +using Android.Views.Autofill; +using Android.Widget; namespace keepass2android.services.AutofillBase { @@ -47,6 +49,7 @@ namespace keepass2android.services.AutofillBase try { query = parser.ParseForFill(); + } catch (Java.Lang.SecurityException e) { @@ -56,20 +59,30 @@ namespace keepass2android.services.AutofillBase } AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; - var responseBuilder = new FillResponse.Builder(); - // Check user's settings for authenticating Responses and Datasets. + bool responseAuth = true; var autofillIds = autofillFields.GetAutofillIds(); if (responseAuth && autofillIds.Length != 0) { + var responseBuilder = new FillResponse.Builder(); // If the entire Autofill Response is authenticated, AuthActivity is used // to generate Response. var sender = IntentBuilder.GetAuthIntentSenderForResponse(this, query); - var presentation = keepass2android.services.AutofillBase.AutofillHelper + RemoteViews presentation = keepass2android.services.AutofillBase.AutofillHelper .NewRemoteViews(PackageName, GetString(Resource.String.autofill_sign_in_prompt), Resource.Drawable.ic_launcher); - responseBuilder - .SetAuthentication(autofillIds, sender, presentation); + + var datasetBuilder = new Dataset.Builder(presentation); + + datasetBuilder + .SetAuthentication(sender); + foreach (var autofillId in autofillIds) + { + datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER")); + } + + responseBuilder.AddDataset(datasetBuilder.Build()); + callback.OnSuccess(responseBuilder.Build()); } else diff --git a/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs b/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs index de501975..91b9e803 100644 --- a/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs +++ b/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs @@ -22,7 +22,7 @@ namespace keepass2android.services.AutofillBase public static string ExtraQueryString => "EXTRA_QUERY_STRING"; - public int RequestCodeQuery => 663245; + public int RequestCodeQuery => 6245; protected override void OnCreate(Bundle savedInstanceState) { @@ -48,6 +48,11 @@ namespace keepass2android.services.AutofillBase StartActivityForResult(i, RequestCodeQuery); } + protected override void OnStart() + { + base.OnStart(); + } + protected abstract Intent GetQueryIntent(string requestedUrl); protected void RestartApp() @@ -80,21 +85,12 @@ namespace keepass2android.services.AutofillBase protected void OnSuccess(FilledAutofillFieldCollection clientFormDataMap) { var intent = Intent; - var forResponse = intent.GetBooleanExtra(CommonUtil.EXTRA_FOR_RESPONSE, true); AssistStructure structure = (AssistStructure)intent.GetParcelableExtra(AutofillManager.ExtraAssistStructure); StructureParser parser = new StructureParser(this, structure); parser.ParseForFill(); AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; ReplyIntent = new Intent(); - if (forResponse) - { - Dictionary dict = new Dictionary { {clientFormDataMap.DatasetName, clientFormDataMap }}; - SetResponseIntent(AutofillHelper.NewResponse(this, false, autofillFields, dict, IntentBuilder)); - } - else - { - SetDatasetIntent(AutofillHelper.NewDataset(this, autofillFields, clientFormDataMap, false, IntentBuilder)); - } + SetDatasetIntent(AutofillHelper.NewDataset(this, autofillFields, clientFormDataMap, false, IntentBuilder)); } protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) @@ -103,16 +99,21 @@ namespace keepass2android.services.AutofillBase if (requestCode == RequestCodeQuery) { - if (resultCode != Result.Ok) - OnFailure(); - else + if (resultCode == ExpectedActivityResult) OnSuccess(GetDataset(data)); + else + OnFailure(); Finish(); } } + protected virtual Result ExpectedActivityResult + { + get { return Result.Ok; } + } + /// /// Creates the FilledAutofillFieldCollection from the intent returned from the query activity /// diff --git a/src/keepass2android/services/AutofillBase/CommonUtil.cs b/src/keepass2android/services/AutofillBase/CommonUtil.cs index c6305eea..498abbef 100644 --- a/src/keepass2android/services/AutofillBase/CommonUtil.cs +++ b/src/keepass2android/services/AutofillBase/CommonUtil.cs @@ -1,6 +1,7 @@ using System; using System.Text; using Android.OS; +using Android.Util; using Java.Util; namespace keepass2android.services.AutofillBase @@ -9,8 +10,6 @@ namespace keepass2android.services.AutofillBase { public const string Tag = "Kp2aAutofill"; public const bool Debug = true; - public const string EXTRA_DATASET_NAME = "dataset_name"; - public const string EXTRA_FOR_RESPONSE = "for_response"; static void BundleToString(StringBuilder builder, Bundle data) { @@ -43,5 +42,17 @@ namespace keepass2android.services.AutofillBase BundleToString(builder, data); return builder.ToString(); } + + public static void logd(string s) + { +#if DEBUG + Log.Debug(Tag, s); +#endif + } + + public static void loge(string s) + { + Kp2aLog.Log(s); + } } } \ No newline at end of file diff --git a/src/keepass2android/services/AutofillBase/StructureParser.cs b/src/keepass2android/services/AutofillBase/StructureParser.cs index 5966db3c..282543ab 100644 --- a/src/keepass2android/services/AutofillBase/StructureParser.cs +++ b/src/keepass2android/services/AutofillBase/StructureParser.cs @@ -52,20 +52,21 @@ namespace keepass2android.services.AutofillBase var view = node.RootViewNode; ParseLocked(forFill, view, ref webDomain); } - if (!string.IsNullOrEmpty(webDomain)) + String packageName = Structure.ActivityComponent.PackageName; + if (!string.IsNullOrEmpty(webDomain)) { - String packageName = Structure.ActivityComponent.PackageName; bool valid = Kp2aDigitalAssetLinksDataSource.Instance.IsValid(mContext, webDomain, packageName); if (!valid) { throw new Java.Lang.SecurityException(mContext.GetString( Resource.String.invalid_link_association, webDomain, packageName)); } - Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, $"Domain {webDomain} is valid for {packageName}"); + Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, $"Domain {webDomain} is valid for {packageName}"); } else { - Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, "no web domain"); + webDomain = "androidapp://" + packageName; + Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, "no web domain. Using package name."); } return webDomain; } @@ -93,7 +94,7 @@ namespace keepass2android.services.AutofillBase { if (forFill) { - AutofillFields.Add(new keepass2android.services.AutofillBase.AutofillFieldMetadata(viewNode)); + AutofillFields.Add(new AutofillFieldMetadata(viewNode)); } else { diff --git a/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs b/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs index 8af0be3b..7ae92034 100644 --- a/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs +++ b/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs @@ -11,12 +11,13 @@ namespace keepass2android.services.AutofillBase.model public string[] AutofillHints { get; set; } + public FilledAutofillField() {} - public FilledAutofillField(AssistStructure.ViewNode viewNode) + /*public FilledAutofillField(AssistStructure.ViewNode viewNode) { - AutofillHints = AutofillHelper.FilterForSupportedHints(viewNode.GetAutofillHints()); + AutofillHintsHelper = AutofillHelper.FilterForSupportedHints(viewNode.GetAutofillHints()); //TODO port updated FilledAutofillField? AutofillValue autofillValue = viewNode.AutofillValue; @@ -40,7 +41,7 @@ namespace keepass2android.services.AutofillBase.model TextValue = autofillValue.TextValue; } } - } + }*/ public bool IsNull() { diff --git a/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs b/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs index 393874ea..2454d98c 100644 --- a/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs +++ b/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs @@ -32,26 +32,114 @@ namespace keepass2android.services.AutofillBase.model public void Add(FilledAutofillField filledAutofillField) { string[] autofillHints = filledAutofillField.AutofillHints; - //TODO apply W3C transformation - foreach (string hint in autofillHints) - { - HintMap.Add(hint, filledAutofillField); - } + + string nextHint = null; + for (int i = 0; i < autofillHints.Length; i++) + { + string hint = autofillHints[i]; + if (i < autofillHints.Length - 1) + { + nextHint = autofillHints[i + 1]; + } + // First convert the compound W3C autofill hints + if (isW3cSectionPrefix(hint) && i < autofillHints.Length - 1) + { + hint = autofillHints[++i]; + CommonUtil.logd($"Hint is a W3C section prefix; using {hint} instead"); + if (i < autofillHints.Length - 1) + { + nextHint = autofillHints[i + 1]; + } + } + if (isW3cTypePrefix(hint) && nextHint != null && isW3cTypeHint(nextHint)) + { + hint = nextHint; + i++; + CommonUtil.logd($"Hint is a W3C type prefix; using {hint} instead"); + } + if (isW3cAddressType(hint) && nextHint != null) + { + hint = nextHint; + i++; + CommonUtil.logd($"Hint is a W3C address prefix; using {hint} instead"); + } + + // Then check if the "actual" hint is supported. + if (AutofillHintsHelper.IsValidHint(hint)) + { + HintMap.Add(hint, filledAutofillField); + } + else + { + CommonUtil.loge($"Invalid hint: {autofillHints[i]}"); + } + } + } - /// - /// Populates a Dataset.Builder with appropriate values for each AutofillId - /// in a AutofillFieldMetadataCollection. - /// - /// In other words, it constructs an autofill Dataset.Builder - /// by applying saved values (from this FilledAutofillFieldCollection) - /// to Views specified in a AutofillFieldMetadataCollection, which represents the current - /// page the user is on. - /// - /// true, if to fields was applyed, false otherwise. - /// Autofill field metadata collection. - /// Dataset builder. - public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection, + + private static bool isW3cSectionPrefix(string hint) + { + return hint.StartsWith(W3cHints.PREFIX_SECTION); + } + + private static bool isW3cAddressType(string hint) + { + switch (hint) + { + case W3cHints.SHIPPING: + case W3cHints.BILLING: + return true; + } + return false; + } + + private static bool isW3cTypePrefix(string hint) + { + switch (hint) + { + case W3cHints.PREFIX_WORK: + case W3cHints.PREFIX_FAX: + case W3cHints.PREFIX_HOME: + case W3cHints.PREFIX_PAGER: + return true; + } + return false; + } + + private static bool isW3cTypeHint(string hint) + { + switch (hint) + { + case W3cHints.TEL: + case W3cHints.TEL_COUNTRY_CODE: + case W3cHints.TEL_NATIONAL: + case W3cHints.TEL_AREA_CODE: + case W3cHints.TEL_LOCAL: + case W3cHints.TEL_LOCAL_PREFIX: + case W3cHints.TEL_LOCAL_SUFFIX: + case W3cHints.TEL_EXTENSION: + case W3cHints.EMAIL: + case W3cHints.IMPP: + return true; + } + Log.Warn(CommonUtil.Tag, "Invalid W3C type hint: " + hint); + return false; + } + + /// + /// Populates a Dataset.Builder with appropriate values for each AutofillId + /// in a AutofillFieldMetadataCollection. + /// + /// In other words, it constructs an autofill Dataset.Builder + /// by applying saved values (from this FilledAutofillFieldCollection) + /// to Views specified in a AutofillFieldMetadataCollection, which represents the current + /// page the user is on. + /// + /// true, if to fields was applyed, false otherwise. + /// Autofill field metadata collection. + /// Dataset builder. + public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection, Dataset.Builder datasetBuilder) { bool setValueAtLeastOnce = false; @@ -66,8 +154,8 @@ namespace keepass2android.services.AutofillBase.model } for (int autofillFieldIndex = 0; autofillFieldIndex < fillableAutofillFields.Count; autofillFieldIndex++) { - keepass2android.services.AutofillBase.model.FilledAutofillField filledAutofillField = HintMap[hint]; - if (filledAutofillField == null) + FilledAutofillField filledAutofillField; + if (!HintMap.TryGetValue(hint, out filledAutofillField) || (filledAutofillField == null)) { continue; } diff --git a/src/keepass2android/services/AutofillBase/model/W3cHints.cs b/src/keepass2android/services/AutofillBase/model/W3cHints.cs index 11941ea1..fb96fad6 100644 --- a/src/keepass2android/services/AutofillBase/model/W3cHints.cs +++ b/src/keepass2android/services/AutofillBase/model/W3cHints.cs @@ -4,68 +4,68 @@ { // Supported W3C autofill tokens (https://html.spec.whatwg.org/multipage/forms.html#autofill) - public static string HONORIFIC_PREFIX = "honorific-prefix"; - public static string NAME = "name"; - public static string GIVEN_NAME = "given-name"; - public static string ADDITIONAL_NAME = "additional-name"; - public static string FAMILY_NAME = "family-name"; - public static string HONORIFIC_SUFFIX = "honorific-suffix"; - public static string USERNAME = "username"; - public static string NEW_PASSWORD = "new-password"; - public static string CURRENT_PASSWORD = "current-password"; - public static string ORGANIZATION_TITLE = "organization-title"; - public static string ORGANIZATION = "organization"; - public static string STREET_ADDRESS = "street-address"; - public static string ADDRESS_LINE1 = "address-line1"; - public static string ADDRESS_LINE2 = "address-line2"; - public static string ADDRESS_LINE3 = "address-line3"; - public static string ADDRESS_LEVEL4 = "address-level4"; - public static string ADDRESS_LEVEL3 = "address-level3"; - public static string ADDRESS_LEVEL2 = "address-level2"; - public static string ADDRESS_LEVEL1 = "address-level1"; - public static string COUNTRY = "country"; - public static string COUNTRY_NAME = "country-name"; - public static string POSTAL_CODE = "postal-code"; - public static string CC_NAME = "cc-name"; - public static string CC_GIVEN_NAME = "cc-given-name"; - public static string CC_ADDITIONAL_NAME = "cc-additional-name"; - public static string CC_FAMILY_NAME = "cc-family-name"; - public static string CC_NUMBER = "cc-number"; - public static string CC_EXPIRATION = "cc-exp"; - public static string CC_EXPIRATION_MONTH = "cc-exp-month"; - public static string CC_EXPIRATION_YEAR = "cc-exp-year"; - public static string CC_CSC = "cc-csc"; - public static string CC_TYPE = "cc-type"; - public static string TRANSACTION_CURRENCY = "transaction-currency"; - public static string TRANSACTION_AMOUNT = "transaction-amount"; - public static string LANGUAGE = "language"; - public static string BDAY = "bday"; - public static string BDAY_DAY = "bday-day"; - public static string BDAY_MONTH = "bday-month"; - public static string BDAY_YEAR = "bday-year"; - public static string SEX = "sex"; - public static string URL = "url"; - public static string PHOTO = "photo"; + public const string HONORIFIC_PREFIX = "honorific-prefix"; + public const string NAME = "name"; + public const string GIVEN_NAME = "given-name"; + public const string ADDITIONAL_NAME = "additional-name"; + public const string FAMILY_NAME = "family-name"; + public const string HONORIFIC_SUFFIX = "honorific-suffix"; + public const string USERNAME = "username"; + public const string NEW_PASSWORD = "new-password"; + public const string CURRENT_PASSWORD = "current-password"; + public const string ORGANIZATION_TITLE = "organization-title"; + public const string ORGANIZATION = "organization"; + public const string STREET_ADDRESS = "street-address"; + public const string ADDRESS_LINE1 = "address-line1"; + public const string ADDRESS_LINE2 = "address-line2"; + public const string ADDRESS_LINE3 = "address-line3"; + public const string ADDRESS_LEVEL4 = "address-level4"; + public const string ADDRESS_LEVEL3 = "address-level3"; + public const string ADDRESS_LEVEL2 = "address-level2"; + public const string ADDRESS_LEVEL1 = "address-level1"; + public const string COUNTRY = "country"; + public const string COUNTRY_NAME = "country-name"; + public const string POSTAL_CODE = "postal-code"; + public const string CC_NAME = "cc-name"; + public const string CC_GIVEN_NAME = "cc-given-name"; + public const string CC_ADDITIONAL_NAME = "cc-additional-name"; + public const string CC_FAMILY_NAME = "cc-family-name"; + public const string CC_NUMBER = "cc-number"; + public const string CC_EXPIRATION = "cc-exp"; + public const string CC_EXPIRATION_MONTH = "cc-exp-month"; + public const string CC_EXPIRATION_YEAR = "cc-exp-year"; + public const string CC_CSC = "cc-csc"; + public const string CC_TYPE = "cc-type"; + public const string TRANSACTION_CURRENCY = "transaction-currency"; + public const string TRANSACTION_AMOUNT = "transaction-amount"; + public const string LANGUAGE = "language"; + public const string BDAY = "bday"; + public const string BDAY_DAY = "bday-day"; + public const string BDAY_MONTH = "bday-month"; + public const string BDAY_YEAR = "bday-year"; + public const string SEX = "sex"; + public const string URL = "url"; + public const string PHOTO = "photo"; // Optional W3C prefixes - public static string PREFIX_SECTION = "section-"; - public static string SHIPPING = "shipping"; - public static string BILLING = "billing"; + public const string PREFIX_SECTION = "section-"; + public const string SHIPPING = "shipping"; + public const string BILLING = "billing"; // W3C prefixes below... - public static string PREFIX_HOME = "home"; - public static string PREFIX_WORK = "work"; - public static string PREFIX_FAX = "fax"; - public static string PREFIX_PAGER = "pager"; + public const string PREFIX_HOME = "home"; + public const string PREFIX_WORK = "work"; + public const string PREFIX_FAX = "fax"; + public const string PREFIX_PAGER = "pager"; // ... require those suffix - public static string TEL = "tel"; - public static string TEL_COUNTRY_CODE = "tel-country-code"; - public static string TEL_NATIONAL = "tel-national"; - public static string TEL_AREA_CODE = "tel-area-code"; - public static string TEL_LOCAL = "tel-local"; - public static string TEL_LOCAL_PREFIX = "tel-local-prefix"; - public static string TEL_LOCAL_SUFFIX = "tel-local-suffix"; - public static string TEL_EXTENSION = "tel_extension"; - public static string EMAIL = "email"; - public static string IMPP = "impp"; + public const string TEL = "tel"; + public const string TEL_COUNTRY_CODE = "tel-country-code"; + public const string TEL_NATIONAL = "tel-national"; + public const string TEL_AREA_CODE = "tel-area-code"; + public const string TEL_LOCAL = "tel-local"; + public const string TEL_LOCAL_PREFIX = "tel-local-prefix"; + public const string TEL_LOCAL_SUFFIX = "tel-local-suffix"; + public const string TEL_EXTENSION = "tel_extension"; + public const string EMAIL = "email"; + public const string IMPP = "impp"; private W3cHints() { diff --git a/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs b/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs index 143a884f..65a758d7 100644 --- a/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs +++ b/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs @@ -34,6 +34,8 @@ namespace keepass2android.services.Kp2aAutofill return i; } + protected override Result ExpectedActivityResult => KeePass.ExitCloseAfterTaskComplete; + protected override FilledAutofillFieldCollection GetDataset(Intent data) { if (!App.Kp2a.GetDb().Loaded || (App.Kp2a.QuickLocked)) @@ -45,13 +47,13 @@ namespace keepass2android.services.Kp2aAutofill FilledAutofillField pwdField = new FilledAutofillField { - AutofillHints = new[] {W3cHints.NAME, W3cHints.EMAIL}, + AutofillHints = new[] {View.AutofillHintPassword}, TextValue = password }; FilledAutofillField userField = new FilledAutofillField { - AutofillHints = new[] {W3cHints.NEW_PASSWORD, W3cHints.CURRENT_PASSWORD}, + AutofillHints = new[] {View.AutofillHintUsername}, TextValue = username }; diff --git a/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs b/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs index d5c10b9c..010e5f4a 100644 --- a/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs +++ b/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs @@ -9,6 +9,7 @@ using Android.Runtime; using Android.Views; using Android.Widget; using keepass2android.services.AutofillBase; +using keepass2android.services.Kp2aAutofill; namespace keepass2android.services { @@ -17,7 +18,8 @@ namespace keepass2android.services public IntentSender GetAuthIntentSenderForResponse(Context context, string query) { - Intent intent = new Intent(context, typeof(KeePass)); + Intent intent = new Intent(context, typeof(ChooseForAutofillActivity)); + intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryString, query); return PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender; }