예제 #1
0
        private void AddDisableDataset(string query, AutofillId[] autofillIds, FillResponse.Builder responseBuilder, bool isManual)
        {
            bool isQueryDisabled = IsQueryDisabled(query);

            if (isQueryDisabled && !isManual)
            {
                return;
            }
            bool isForDisable = !isQueryDisabled;
            var  sender       = IntentBuilder.GetDisableIntentSenderForResponse(this, query, isManual, isForDisable);

            RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName,
                                                                     GetString(isForDisable ? Resource.String.autofill_disable : Resource.String.autofill_enable_for, new Java.Lang.Object[] { GetDisplayNameForQuery(query, this) }), Resource.Drawable.ic_menu_close_grey);

            var datasetBuilder = new Dataset.Builder(presentation);

            datasetBuilder.SetAuthentication(sender);

            foreach (var autofillId in autofillIds)
            {
                datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
            }

            responseBuilder.AddDataset(datasetBuilder.Build());
        }
        private List <Dataset> BuildEntryDatasets(string query, string queryDomain, string queryPackage, AutofillId[] autofillIds, StructureParser parser,
                                                  DisplayWarning warning)
        {
            List <Dataset> result = new List <Dataset>();

            Kp2aLog.Log("AF: BuildEntryDatasets");
            var suggestedEntries = GetSuggestedEntries(query).ToDictionary(e => e.DatasetName, e => e);

            Kp2aLog.Log("AF: BuildEntryDatasets found " + suggestedEntries.Count + " entries");
            foreach (var filledAutofillFieldCollection in suggestedEntries.Values)
            {
                if (filledAutofillFieldCollection == null)
                {
                    continue;
                }

                if (warning == DisplayWarning.None)
                {
                    FilledAutofillFieldCollection partitionData =
                        AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, parser.AutofillFields.FocusedAutofillCanonicalHints);

                    Kp2aLog.Log("AF: Add dataset");

                    result.Add(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder));
                }
                else
                {
                    //return an "auth" dataset (actually for just warning the user in case domain/package dont match)
                    var sender =
                        IntentBuilder.GetAuthIntentSenderForWarning(this, query, queryDomain, queryPackage, warning);
                    var datasetName = filledAutofillFieldCollection.DatasetName;
                    if (datasetName == null)
                    {
                        Kp2aLog.Log("AF: dataset name is null");
                        continue;
                    }

                    RemoteViews presentation =
                        AutofillHelper.NewRemoteViews(PackageName, datasetName, AppNames.LauncherIcon);

                    var datasetBuilder = new Dataset.Builder(presentation);
                    datasetBuilder.SetAuthentication(sender);
                    //need to add placeholders so we can directly fill after ChooseActivity
                    foreach (var autofillId in autofillIds)
                    {
                        datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
                    }
                    Kp2aLog.Log("AF: Add auth dataset");
                    result.Add(datasetBuilder.Build());
                }
            }

            return(result);
        }
예제 #3
0
        private Dataset AddEntryDataset(string query, StructureParser parser)
        {
            var filledAutofillFieldCollection = GetSuggestedEntry(query);

            if (filledAutofillFieldCollection == null)
            {
                return(null);
            }
            int partitionIndex = AutofillHintsHelper.GetPartitionIndex(parser.AutofillFields.FocusedAutofillCanonicalHints.FirstOrDefault());
            FilledAutofillFieldCollection partitionData = AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, partitionIndex);

            return(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder));
        }
        protected void OnSuccess(FilledAutofillFieldCollection clientFormDataMap, bool isManual)
        {
            var             intent    = Intent;
            AssistStructure structure = (AssistStructure)intent.GetParcelableExtra(AutofillManager.ExtraAssistStructure);
            StructureParser parser    = new StructureParser(this, structure);

            parser.ParseForFill(isManual);
            AutofillFieldMetadataCollection autofillFields = parser.AutofillFields;
            int partitionIndex = AutofillHintsHelper.GetPartitionIndex(autofillFields.FocusedAutofillCanonicalHints.FirstOrDefault());
            FilledAutofillFieldCollection partitionData = AutofillHintsHelper.FilterForPartition(clientFormDataMap, partitionIndex);

            ReplyIntent = new Intent();
            SetDatasetIntent(AutofillHelper.NewDataset(this, autofillFields, partitionData, IntentBuilder));
        }
        protected void OnSuccess(FilledAutofillFieldCollection clientFormDataMap, bool isManual)
        {
            var             intent    = Intent;
            AssistStructure structure = (AssistStructure)intent.GetParcelableExtra(AutofillManager.ExtraAssistStructure);
            StructureParser parser    = new StructureParser(this, structure);

            parser.ParseForFill(isManual);
            AutofillFieldMetadataCollection autofillFields = parser.AutofillFields;
            var partitionData = AutofillHintsHelper.FilterForPartition(clientFormDataMap, parser.AutofillFields.FocusedAutofillCanonicalHints);



            ReplyIntent = new Intent();
            SetDatasetIntent(AutofillHelper.NewDataset(this, autofillFields, partitionData, IntentBuilder, null /*TODO can we get the inlinePresentationSpec here?*/));
            SetResult(Result.Ok, ReplyIntent);
        }
예제 #6
0
        private void AddQueryDataset(string query, string queryDomain, string queryPackage, bool isManual, AutofillId[] autofillIds, FillResponse.Builder responseBuilder, bool autoReturnFromQuery, DisplayWarning warning)
        {
            var         sender       = IntentBuilder.GetAuthIntentSenderForResponse(this, query, queryDomain, queryPackage, isManual, autoReturnFromQuery, warning);
            RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName,
                                                                     GetString(Resource.String.autofill_sign_in_prompt), AppNames.LauncherIcon);

            var datasetBuilder = new Dataset.Builder(presentation);

            datasetBuilder.SetAuthentication(sender);
            //need to add placeholders so we can directly fill after ChooseActivity
            foreach (var autofillId in autofillIds)
            {
                datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
            }

            responseBuilder.AddDataset(datasetBuilder.Build());
        }
예제 #7
0
        private Dataset BuildEntryDataset(string query, string queryDomain, string queryPackage, AutofillId[] autofillIds, StructureParser parser,
                                          DisplayWarning warning)
        {
            var filledAutofillFieldCollection = GetSuggestedEntry(query);

            if (filledAutofillFieldCollection == null)
            {
                return(null);
            }

            if (warning == DisplayWarning.None)
            {
                //can return an actual dataset
                int partitionIndex = AutofillHintsHelper.GetPartitionIndex(parser.AutofillFields.FocusedAutofillCanonicalHints.FirstOrDefault());
                FilledAutofillFieldCollection partitionData = AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, partitionIndex);

                return(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder));
            }
            else
            {
                //return an "auth" dataset (actually for just warning the user in case domain/package dont match)
                var sender      = IntentBuilder.GetAuthIntentSenderForWarning(this, query, queryDomain, queryPackage, warning);
                var datasetName = filledAutofillFieldCollection.DatasetName;
                if (datasetName == null)
                {
                    return(null);
                }

                RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, datasetName, AppNames.LauncherIcon);

                var datasetBuilder = new Dataset.Builder(presentation);
                datasetBuilder.SetAuthentication(sender);
                //need to add placeholders so we can directly fill after ChooseActivity
                foreach (var autofillId in autofillIds)
                {
                    datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
                }

                return(datasetBuilder.Build());
            }
        }
예제 #8
0
        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.");
            }
        }
예제 #9
0
        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
            string 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;

            bool responseAuth = true;
            var  autofillIds  = autofillFields.GetAutofillIds();

            if (responseAuth && autofillIds.Length != 0 && CanAutofill(query))
            {
                var responseBuilder = new FillResponse.Builder();

                var         sender       = IntentBuilder.GetAuthIntentSenderForResponse(this, query, isManual);
                RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, GetString(Resource.String.autofill_sign_in_prompt), AppNames.LauncherIcon);

                var datasetBuilder = new Dataset.Builder(presentation);
                datasetBuilder.SetAuthentication(sender);
                //need to add placeholders so we can directly fill after ChooseActivity
                foreach (var autofillId in autofillIds)
                {
                    datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
                }

                responseBuilder.AddDataset(datasetBuilder.Build());

                callback.OnSuccess(responseBuilder.Build());
            }
            else
            {
                var datasetAuth = true;
                var response    = AutofillHelper.NewResponse(this, datasetAuth, autofillFields, null, IntentBuilder);
                callback.OnSuccess(response);
            }
        }