private bool CanAutofill(StructureParser.AutofillTargetId query, bool isManual) { if (query.PackageNameWithPseudoSchema == KeePass.AndroidAppScheme + "android" || query.PackageNameWithPseudoSchema == KeePass.AndroidAppScheme + this.PackageName) { return(false); } if (!isManual) { var isQueryDisabled = IsQueryDisabled(query.DomainOrPackage); if (isQueryDisabled) { return(false); } } return(true); }
public override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback) { bool isManual = (request.Flags & FillRequest.FlagManualRequest) != 0; CommonUtil.logd("onFillRequest " + (isManual ? "manual" : "auto")); var structure = request.FillContexts[request.FillContexts.Count - 1].Structure; //TODO support package signature verification as soon as this is supported in Keepass storage var clientState = request.ClientState; CommonUtil.logd("onFillRequest(): data=" + CommonUtil.BundleToString(clientState)); cancellationSignal.CancelEvent += (sender, e) => { Log.Warn(CommonUtil.Tag, "Cancel autofill not implemented yet."); }; // Parse AutoFill data in Activity StructureParser.AutofillTargetId query = null; var parser = new StructureParser(this, structure); try { query = parser.ParseForFill(isManual); } catch (Java.Lang.SecurityException e) { Log.Warn(CommonUtil.Tag, "Security exception handling request"); callback.OnFailure(e.Message); return; } AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; var autofillIds = autofillFields.GetAutofillIds(); if (autofillIds.Length != 0 && CanAutofill(query, isManual)) { var responseBuilder = new FillResponse.Builder(); Dataset entryDataset = null; if (query.IncompatiblePackageAndDomain == false) { //domain and package are compatible. Use Domain if available and package otherwise. Can fill without warning. entryDataset = BuildEntryDataset(query.DomainOrPackage, query.WebDomain, query.PackageName, autofillIds, parser, DisplayWarning.None); } else { //domain or package are incompatible. Don't show the entry. (Tried to do so first but behavior was not consistent) //entryDataset = BuildEntryDataset(query.WebDomain, query.WebDomain, query.PackageName, autofillIds, parser, DisplayWarning.FillDomainInUntrustedApp); } bool hasEntryDataset = entryDataset != null; if (entryDataset != null) { responseBuilder.AddDataset(entryDataset); } if (query.WebDomain != null) { AddQueryDataset(query.WebDomain, query.WebDomain, query.PackageName, isManual, autofillIds, responseBuilder, !hasEntryDataset, query.IncompatiblePackageAndDomain ? DisplayWarning.FillDomainInUntrustedApp : DisplayWarning.None); } else { AddQueryDataset(query.PackageNameWithPseudoSchema, query.WebDomain, query.PackageName, isManual, autofillIds, responseBuilder, !hasEntryDataset, DisplayWarning.None); } AddDisableDataset(query.DomainOrPackage, autofillIds, responseBuilder, isManual); if (PreferenceManager.GetDefaultSharedPreferences(this) .GetBoolean(GetString(Resource.String.OfferSaveCredentials_key), true)) { if (!CompatBrowsers.Contains(parser.PackageId)) { responseBuilder.SetSaveInfo(new SaveInfo.Builder(parser.AutofillFields.SaveType, parser.AutofillFields.GetAutofillIds()).Build()); } } callback.OnSuccess(responseBuilder.Build()); } else { callback.OnSuccess(null); } }
protected abstract void HandleSaveRequest(StructureParser parser, StructureParser.AutofillTargetId query);
public override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback) { bool isManual = (request.Flags & FillRequest.FlagManualRequest) != 0; CommonUtil.logd("onFillRequest " + (isManual ? "manual" : "auto")); var structure = request.FillContexts.Last().Structure; if (_lockTime + _lockTimeout < DateTime.Now) { _lockTime = DateTime.Now; //TODO support package signature verification as soon as this is supported in Keepass storage var clientState = request.ClientState; CommonUtil.logd("onFillRequest(): data=" + CommonUtil.BundleToString(clientState)); cancellationSignal.CancelEvent += (sender, e) => { Kp2aLog.Log("Cancel autofill not implemented yet."); _lockTime = DateTime.MinValue; }; // Parse AutoFill data in Activity StructureParser.AutofillTargetId query = null; var parser = new StructureParser(this, structure); try { query = parser.ParseForFill(isManual); } catch (Java.Lang.SecurityException e) { Log.Warn(CommonUtil.Tag, "Security exception handling request"); callback.OnFailure(e.Message); return; } AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; InlineSuggestionsRequest inlineSuggestionsRequest = null; IList <InlinePresentationSpec> inlinePresentationSpecs = null; if (((int)Build.VERSION.SdkInt >= 30) && (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.InlineSuggestions_key), true))) { inlineSuggestionsRequest = request.InlineSuggestionsRequest; inlinePresentationSpecs = inlineSuggestionsRequest?.InlinePresentationSpecs; } var autofillIds = autofillFields.GetAutofillIds(); if (autofillIds.Length != 0 && CanAutofill(query, isManual)) { var responseBuilder = new FillResponse.Builder(); bool hasEntryDataset = false; IList <Dataset> entryDatasets = new List <Dataset>(); if (query.IncompatiblePackageAndDomain == false) { Kp2aLog.Log("AF: (query.IncompatiblePackageAndDomain == false)"); //domain and package are compatible. Use Domain if available and package otherwise. Can fill without warning. entryDatasets = BuildEntryDatasets(query.DomainOrPackage, query.WebDomain, query.PackageName, autofillIds, parser, DisplayWarning.None, inlinePresentationSpecs ).Where(ds => ds != null).ToList(); if (entryDatasets.Count > inlineSuggestionsRequest?.MaxSuggestionCount - 2 /*disable dataset and query*/) { //we have too many elements. disable inline suggestions inlinePresentationSpecs = null; entryDatasets = BuildEntryDatasets(query.DomainOrPackage, query.WebDomain, query.PackageName, autofillIds, parser, DisplayWarning.None, null ).Where(ds => ds != null).ToList(); } foreach (var entryDataset in entryDatasets ) { Kp2aLog.Log("AF: Got EntryDataset " + (entryDataset == null)); responseBuilder.AddDataset(entryDataset); hasEntryDataset = true; } } { if (query.WebDomain != null) { AddQueryDataset(query.WebDomain, query.WebDomain, query.PackageName, isManual, autofillIds, responseBuilder, !hasEntryDataset, query.IncompatiblePackageAndDomain ? DisplayWarning.FillDomainInUntrustedApp : DisplayWarning.None, AutofillHelper.ExtractSpec(inlinePresentationSpecs, entryDatasets.Count)); } else { AddQueryDataset(query.PackageNameWithPseudoSchema, query.WebDomain, query.PackageName, isManual, autofillIds, responseBuilder, !hasEntryDataset, DisplayWarning.None, AutofillHelper.ExtractSpec(inlinePresentationSpecs, entryDatasets.Count)); } } if (!PreferenceManager.GetDefaultSharedPreferences(this) .GetBoolean(GetString(Resource.String.NoAutofillDisabling_key), false)) { AddDisableDataset(query.DomainOrPackage, autofillIds, responseBuilder, isManual, AutofillHelper.ExtractSpec(inlinePresentationSpecs, entryDatasets.Count)); } if (PreferenceManager.GetDefaultSharedPreferences(this) .GetBoolean(GetString(Resource.String.OfferSaveCredentials_key), true)) { if (!CompatBrowsers.Contains(parser.PackageId)) { responseBuilder.SetSaveInfo(new SaveInfo.Builder(parser.AutofillFields.SaveType, parser.AutofillFields.GetAutofillIds()).Build()); } } Kp2aLog.Log("return autofill success"); callback.OnSuccess(responseBuilder.Build()); } else { Kp2aLog.Log("cannot autofill"); callback.OnSuccess(null); } } else { Kp2aLog.Log("Ignoring onFillRequest as there is another request going on."); } }