public override void OnProvideAutofillVirtualStructure(ViewStructure structure, AutofillFlags flags)
        {
            // Build a ViewStructure that will get passed to the AutofillService by the framework
            // when it is time to find autofill suggestions.
            structure.SetClassName(Class.Name);
            var childrenSize = VirtualViews.Size();

            Log.Debug(LogTag, "onProvideAutofillVirtualStructure(): flags = " + flags + ", items = "
                      + childrenSize + ", extras: " + CommonUtil.BundleToString(structure.Extras));
            var index = structure.AddChildCount(childrenSize);

            // Traverse through the view hierarchy, including virtual child views. For each view, we
            // need to set the relevant autofill metadata and add it to the ViewStructure.
            for (int i = 0; i < childrenSize; i++)
            {
                Item item = VirtualViews.ValueAt(i);
                Log.Debug(LogTag, "Adding new child at index " + index + ": " + item);
                var child = structure.NewChild(index);
                child.SetAutofillId(structure.AutofillId, item.Id);
                child.SetAutofillHints(item.Hints);
                child.SetAutofillType(item.Type);
                child.SetDataIsSensitive(!item.Sanitized);
                child.Text = item.Text;
                child.SetAutofillValue(AutofillValue.ForText(item.Text));
                child.SetFocused(item.Focused);
                child.SetId(item.Id, Context.PackageName, null, item.Line.IdEntry);
                child.SetClassName(item.getClassName());
                index++;
            }
        }
        private static String getAutofillValueAndTypeAsString(AutofillValue value)
        {
            if (value == null)
            {
                return("null");
            }

            var builder = new StringBuilder(value.ToString()).Append('(');

            if (value.IsText)
            {
                builder.Append("isText");
            }
            else if (value.IsDate)
            {
                builder.Append("isDate");
            }
            else if (value.IsToggle)
            {
                builder.Append("isToggle");
            }
            else if (value.IsList)
            {
                builder.Append("isList");
            }
            return(builder.Append(')').ToString());
        }
Exemple #3
0
        public FilledAutofillField(AssistStructure.ViewNode viewNode)
        {
            AutofillHints = AutofillHelper.FilterForSupportedHints(viewNode.GetAutofillHints());
            AutofillValue autofillValue = viewNode.AutofillValue;

            if (autofillValue != null)
            {
                if (autofillValue.IsList)
                {
                    string[] 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;
                }
            }
        }
Exemple #4
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());
        }
        /// <summary>
        /// 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.
        /// </summary>
        /// <returns><c>true</c>, if to fields was applyed, <c>false</c> otherwise.</returns>
        /// <param name="autofillFieldMetadataCollection">Autofill field metadata collection.</param>
        /// <param name="datasetBuilder">Dataset builder.</param>
        public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection, Dataset.Builder datasetBuilder)
        {
            bool setValueAtLeastOnce = false;

            foreach (string hint in autofillFieldMetadataCollection.AllAutofillCanonicalHints)
            {
                foreach (AutofillFieldMetadata autofillFieldMetadata in autofillFieldMetadataCollection.GetFieldsForHint(hint))
                {
                    FilledAutofillField filledAutofillField;
                    if (!HintMap.TryGetValue(hint, out filledAutofillField) || (filledAutofillField == null))
                    {
                        continue;
                    }

                    var autofillId   = autofillFieldMetadata.AutofillId;
                    var autofillType = autofillFieldMetadata.AutofillType;
                    switch (autofillType)
                    {
                    case AutofillType.List:
                        var listValue = autofillFieldMetadata.GetAutofillOptionIndex(filledAutofillField.TextValue);
                        if (listValue != -1)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForList(listValue));
                            setValueAtLeastOnce = true;
                        }
                        break;

                    case AutofillType.Date:
                        var dateValue = filledAutofillField.DateValue;
                        datasetBuilder.SetValue(autofillId, AutofillValue.ForDate((long)dateValue));
                        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;

                    default:
                        Log.Warn(CommonUtil.Tag, "Invalid autofill type - " + autofillType);
                        break;
                    }
                }
            }
            return(setValueAtLeastOnce);
        }
Exemple #6
0
        public static Dataset BuildVaultDataset(Context context, FieldCollection fields, string uri, bool locked,
                                                IList <InlinePresentationSpec> inlinePresentationSpecs = null)
        {
            var intent = new Intent(context, typeof(MainActivity));

            intent.PutExtra("autofillFramework", true);
            if (fields.FillableForLogin)
            {
                intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Login);
            }
            else if (fields.FillableForCard)
            {
                intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Card);
            }
            else if (fields.FillableForIdentity)
            {
                intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Identity);
            }
            else
            {
                return(null);
            }
            intent.PutExtra("autofillFrameworkUri", uri);
            var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent,
                                                          PendingIntentFlags.CancelCurrent);

            var overlayPresentation = BuildOverlayPresentation(
                AppResources.AutofillWithBitwarden,
                locked ? AppResources.VaultIsLocked : AppResources.GoToMyVault,
                Resource.Drawable.icon,
                context);

            var inlinePresentation = BuildInlinePresentation(
                inlinePresentationSpecs?.Last(),
                AppResources.Bitwarden,
                locked ? AppResources.VaultIsLocked : AppResources.MyVault,
                Resource.Drawable.icon,
                pendingIntent,
                context);

            var datasetBuilder = new Dataset.Builder(overlayPresentation);

            if (inlinePresentation != null)
            {
                datasetBuilder.SetInlinePresentation(inlinePresentation);
            }
            datasetBuilder.SetAuthentication(pendingIntent?.IntentSender);

            // Dataset must have a value set. We will reset this in the main activity when the real item is chosen.
            foreach (var autofillId in fields.AutofillIds)
            {
                datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
            }
            return(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);
        }
        private static AutofillValue ApplyValue(Field field, string value, bool monthValue = false)
        {
            switch (field.AutofillType)
            {
            case AutofillType.Date:
                if (long.TryParse(value, out long dateValue))
                {
                    return(AutofillValue.ForDate(dateValue));
                }
                break;

            case AutofillType.List:
                if (field.AutofillOptions != null)
                {
                    if (monthValue && int.TryParse(value, out int monthIndex))
                    {
                        if (field.AutofillOptions.Count == 13)
                        {
                            return(AutofillValue.ForList(monthIndex));
                        }
                        else if (field.AutofillOptions.Count >= monthIndex)
                        {
                            return(AutofillValue.ForList(monthIndex - 1));
                        }
                    }

                    for (var i = 0; i < field.AutofillOptions.Count; i++)
                    {
                        if (field.AutofillOptions[i].Equals(value))
                        {
                            return(AutofillValue.ForList(i));
                        }
                    }
                }
                break;

            case AutofillType.Text:
                return(AutofillValue.ForText(value));

            case AutofillType.Toggle:
                if (bool.TryParse(value, out bool toggleValue))
                {
                    return(AutofillValue.ForToggle(toggleValue));
                }
                break;

            default:
                break;
            }

            return(null);
        }
Exemple #9
0
            public AutofillValue GetAutofillValue()
            {
                switch (type)
                {
                case AutofillType.Text:
                    return((TextUtils.GetTrimmedLength(text) > 0)
                                                        ? AutofillValue.ForText(text)
                                                        : null);

                case AutofillType.Date:
                    return(AutofillValue.ForDate(date));

                default:
                    return(null);
                }
            }
        public override void Autofill(AutofillValue value)
        {
            if (!value.IsDate)
            {
                Log.Warn(CommonUtil.TAG, "Ignoring autofill() because service sent a non-date value:" + value);
                return;
            }

            var calendar = Calendar.Instance;

            calendar.TimeInMillis = value.DateValue;
            var month = calendar.Get(CalendarField.Month);
            var year  = calendar.Get(CalendarField.Year);

            mCcExpMonthSpinner.SetSelection(month);
            mCcExpYearSpinner.SetSelection(year - Integer.ParseInt(mYears[0]));
        }
Exemple #11
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());
        }
        public override void Autofill(AutofillValue value)
        {
            if (value == null || !value.IsDate)
            {
                Log.Warn(CommonUtil.TAG, "autofill(): invalid value " + value);
                return;
            }
            var time = value.DateValue;

            mTempCalendar.TimeInMillis = time;
            var year  = mTempCalendar.Get(CalendarField.Year);
            var month = mTempCalendar.Get(CalendarField.Month);

            if (CommonUtil.DEBUG)
            {
                Log.Debug(CommonUtil.TAG, "autofill(" + value + "): " + month + "/" + year);
            }
            SetDate(year, month);
        }
Exemple #13
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());
            }
        }
Exemple #14
0
        public FilledAutofillField(AssistStructure.ViewNode viewNode, string[] hints)
        {
            string[]      rawHints = AutofillHintsHelper.FilterForSupportedHints(hints);
            List <string> hintList = new List <string>();

            string nextHint = null;

            for (int i = 0; i < rawHints.Length; i++)
            {
                string hint = rawHints[i];
                if (i < rawHints.Length - 1)
                {
                    nextHint = rawHints[i + 1];
                }
                // First convert the compound W3C autofill hints
                if (W3cHints.isW3cSectionPrefix(hint) && i < rawHints.Length - 1)
                {
                    hint = rawHints[++i];
                    CommonUtil.logd($"Hint is a W3C section prefix; using {hint} instead");
                    if (i < rawHints.Length - 1)
                    {
                        nextHint = rawHints[i + 1];
                    }
                }
                if (W3cHints.isW3cTypePrefix(hint) && nextHint != null && W3cHints.isW3cTypeHint(nextHint))
                {
                    hint = nextHint;
                    i++;
                    CommonUtil.logd($"Hint is a W3C type prefix; using {hint} instead");
                }
                if (W3cHints.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.IsSupportedHint(hint))
                {
                    hintList.Add(hint);
                }
                else
                {
                    CommonUtil.loge($"Invalid hint: {rawHints[i]}");
                }
            }
            AutofillHints = AutofillHintsHelper.ConvertToCanonicalHints(hintList.ToArray()).ToArray();

            AutofillValue autofillValue = viewNode.AutofillValue;

            if (autofillValue != null)
            {
                if (autofillValue.IsList)
                {
                    string[] 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)
                {
                    TextValue = autofillValue.TextValue;
                }
            }
        }
        /**
         * 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)
        {
            bool          setValueAtLeastOnce = false;
            List <string> allHints            = autofillFieldMetadataCollection.GetAllHints();

            for (var hintIndex = 0; hintIndex < allHints.Count; hintIndex++)
            {
                string hint = allHints[hintIndex];
                var    fillableAutofillFields = autofillFieldMetadataCollection.GetFieldsForHint(hint);
                if (fillableAutofillFields == null)
                {
                    continue;
                }

                for (var autofillFieldIndex = 0;
                     autofillFieldIndex < fillableAutofillFields.Count;
                     autofillFieldIndex++)
                {
                    var filledAutofillField = mHintMap.FirstOrDefault(x => x.Key == hint);
                    if (filledAutofillField.Value == null)
                    {
                        continue;
                    }

                    var        autofillFieldMetadata = fillableAutofillFields[autofillFieldIndex];
                    AutofillId autofillId            = autofillFieldMetadata.GetId();
                    var        autofillType          = autofillFieldMetadata.GetAutofillType();
                    switch (autofillType)
                    {
                    case AutofillType.List:
                        int listValue =
                            autofillFieldMetadata.GetAutofillOptionIndex(filledAutofillField.Value.GetTextValue());
                        if (listValue != -1)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForList(listValue));
                            setValueAtLeastOnce = true;
                        }

                        break;

                    case AutofillType.Date:
                        var dateValue = filledAutofillField.Value.GetDateValue();
                        if (dateValue != null)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForDate(dateValue));
                            setValueAtLeastOnce = true;
                        }

                        break;

                    case AutofillType.Text:
                        var textValue = filledAutofillField.Value.GetTextValue();
                        if (textValue != null)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForText(textValue));
                            setValueAtLeastOnce = true;
                        }

                        break;

                    case AutofillType.Toggle:
                        var toggleValue = filledAutofillField.Value.GetToggleValue();
                        if (toggleValue != null)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForToggle(toggleValue));
                            setValueAtLeastOnce = true;
                        }

                        break;

                    case  AutofillType.None:
                        break;

                    default:
                        Log.Warn(CommonUtil.TAG, "Invalid autofill type - " + autofillType);
                        break;
                    }
                }
            }

            return(setValueAtLeastOnce);
        }
        /**
         * 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);
        }
        void BindValueToNode(AssistStructure.ViewNode viewNode,
                             FilledAutofillField field, Dataset.Builder builder,
                             MutableBoolean setValueAtLeastOnce)
        {
            AutofillId autofillId = viewNode.AutofillId;

            if (autofillId == null)
            {
                Util.Logw("Autofill ID null for %s", viewNode.ToString());
                return;
            }
            int autofillType = (int)viewNode.AutofillType;

            switch (autofillType)
            {
            case (int)AutofillType.List:
                var options   = viewNode.GetAutofillOptions();
                int listValue = -1;
                if (options != null)
                {
                    listValue = Util.IndexOf(viewNode.GetAutofillOptions(), field.GetTextValue());
                }
                if (listValue != -1)
                {
                    builder.SetValue(autofillId, AutofillValue.ForList(listValue));
                    setValueAtLeastOnce.Value = true;
                }
                break;

            case (int)AutofillType.Date:
                var dateValue = field.GetDateValue();
                if (dateValue != null)
                {
                    builder.SetValue(autofillId, AutofillValue.ForDate(dateValue));
                    setValueAtLeastOnce.Value = true;
                }
                break;

            case (int)AutofillType.Text:
                string textValue = field.GetTextValue();
                if (textValue != null)
                {
                    builder.SetValue(autofillId, AutofillValue.ForText(textValue));
                    setValueAtLeastOnce.Value = true;
                }
                break;

            case (int)AutofillType.Toggle:
                var toggleValue = field.GetToggleValue();
                if (toggleValue != null)
                {
                    builder.SetValue(autofillId, AutofillValue.ForToggle(toggleValue));
                    setValueAtLeastOnce.Value = true;
                }
                break;

            case (int)AutofillType.None:
                break;

            default:
                Util.Logw("Invalid autofill type - %d", autofillType);
                break;
            }
        }
        private void ParseLocked(bool forFill, AssistStructure.ViewNode viewNode, StringBuilder validWebDomain)
        {
            var webDomain = viewNode.WebDomain;

            if (webDomain != null)
            {
                if (CommonUtil.DEBUG)
                {
                    Log.Debug(CommonUtil.TAG, "child web domain: " + webDomain);
                }
                if (validWebDomain.Length() > 0)
                {
                    if (webDomain != validWebDomain.ToString())
                    {
                        throw new SecurityException("Found multiple web domains: valid= "
                                                    + validWebDomain + ", child=" + webDomain);
                    }
                }
                else
                {
                    validWebDomain.Append(webDomain);
                }
            }

            if (viewNode.GetAutofillHints() != null)
            {
                var filteredHints = AutofillHints.FilterForSupportedHints(
                    viewNode.GetAutofillHints());
                if (filteredHints != null && filteredHints.Length > 0)
                {
                    if (forFill)
                    {
                        mAutofillFields.Add(new AutofillFieldMetadata(viewNode));
                    }
                    else
                    {
                        var           filledAutofillField = new FilledAutofillField(viewNode.GetAutofillHints());
                        AutofillValue autofillValue       = viewNode.AutofillValue;
                        if (autofillValue.IsText)
                        {
                            // Using toString of AutofillValue.getTextValue in order to save it to
                            // SharedPreferences.
                            filledAutofillField.SetTextValue(autofillValue.TextValue);
                        }
                        else if (autofillValue.IsDate)
                        {
                            filledAutofillField.SetDateValue(autofillValue.DateValue);
                        }
                        else if (autofillValue.IsList)
                        {
                            filledAutofillField.SetListValue(viewNode.GetAutofillOptions(),
                                                             autofillValue.ListValue);
                        }

                        mFilledAutofillFieldCollection.Add(filledAutofillField);
                    }
                }
            }

            int childrenSize = viewNode.ChildCount;

            if (childrenSize > 0)
            {
                for (int i = 0; i < childrenSize; i++)
                {
                    ParseLocked(forFill, viewNode.GetChildAt(i), validWebDomain);
                }
            }
        }
        /// <summary>
        /// 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.
        /// </summary>
        /// <returns><c>true</c>, if to fields was applyed, <c>false</c> otherwise.</returns>
        /// <param name="autofillFieldMetadataCollection">Autofill field metadata collection.</param>
        /// <param name="datasetBuilder">Dataset builder.</param>
        public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection,
                                  Dataset.Builder datasetBuilder)
        {
            bool          setValueAtLeastOnce = false;
            List <string> allHints            = autofillFieldMetadataCollection.AllAutofillHints;

            for (int hintIndex = 0; hintIndex < allHints.Count; hintIndex++)
            {
                string hint = allHints[hintIndex];
                List <AutofillFieldMetadata> fillableAutofillFields = autofillFieldMetadataCollection.GetFieldsForHint(hint);
                if (fillableAutofillFields == null)
                {
                    continue;
                }
                for (int autofillFieldIndex = 0; autofillFieldIndex < fillableAutofillFields.Count; autofillFieldIndex++)
                {
                    FilledAutofillField filledAutofillField = HintMap[hint];
                    if (filledAutofillField == null)
                    {
                        continue;
                    }
                    AutofillFieldMetadata autofillFieldMetadata = fillableAutofillFields[autofillFieldIndex];
                    var autofillId   = autofillFieldMetadata.AutofillId;
                    var autofillType = autofillFieldMetadata.AutofillType;
                    switch (autofillType)
                    {
                    case AutofillType.List:
                        var listValue = autofillFieldMetadata.GetAutofillOptionIndex(filledAutofillField.TextValue);
                        if (listValue != -1)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForList(listValue));
                            setValueAtLeastOnce = true;
                        }
                        break;

                    case AutofillType.Date:
                        var dateValue = filledAutofillField.DateValue;
                        datasetBuilder.SetValue(autofillId, AutofillValue.ForDate((long)dateValue));
                        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;

                    default:
                        Log.Warn(CommonUtil.Tag, "Invalid autofill type - " + autofillType);
                        break;
                    }
                }
            }
            return(setValueAtLeastOnce);
        }
Exemple #20
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);
            }
        }
        /// <summary>
        /// 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.
        /// </summary>
        /// <returns><c>true</c>, if to fields was applyed, <c>false</c> otherwise.</returns>
        /// <param name="autofillFieldMetadataCollection">Autofill field metadata collection.</param>
        /// <param name="datasetBuilder">Dataset builder.</param>
        public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection, Dataset.Builder datasetBuilder)
        {
            bool setValueAtLeastOnce = false;

            foreach (string hint in autofillFieldMetadataCollection.AllAutofillCanonicalHints)
            {
                foreach (AutofillFieldMetadata autofillFieldMetadata in autofillFieldMetadataCollection.GetFieldsForHint(hint))
                {
                    FilledAutofillField filledAutofillField;
                    if (!HintMap.TryGetValue(hint, out filledAutofillField) || (filledAutofillField == null))
                    {
                        continue;
                    }

                    var autofillId   = autofillFieldMetadata.AutofillId;
                    var autofillType = autofillFieldMetadata.AutofillType;
                    switch (autofillType)
                    {
                    case AutofillType.List:
                        var listValue = autofillFieldMetadata.GetAutofillOptionIndex(filledAutofillField.TextValue);
                        if (listValue != -1)
                        {
                            datasetBuilder.SetValue(autofillId, AutofillValue.ForList(listValue));
                            setValueAtLeastOnce = true;
                        }
                        break;

                    case AutofillType.Date:
                        var dateValue = filledAutofillField.DateValue;
                        datasetBuilder.SetValue(autofillId, AutofillValue.ForDate((long)dateValue));
                        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;

                    default:
                        Log.Warn(CommonUtil.Tag, "Invalid autofill type - " + autofillType);
                        break;
                    }
                }
            }

            /*
             * if (!setValueAtLeastOnce)
             * {
             * Kp2aLog.Log("No value set. Hint keys : " + string.Join(",", HintMap.Keys));
             *      foreach (string hint in autofillFieldMetadataCollection.AllAutofillCanonicalHints)
             * {
             * Kp2aLog.Log("No value set. Hint = " + hint);
             * foreach (AutofillFieldMetadata autofillFieldMetadata in autofillFieldMetadataCollection
             * .GetFieldsForHint(hint))
             * {
             * Kp2aLog.Log("No value set. fieldForHint = " + autofillFieldMetadata.AutofillId.ToString());
             * FilledAutofillField filledAutofillField;
             * if (!HintMap.TryGetValue(hint, out filledAutofillField) || (filledAutofillField == null))
             * {
             *  Kp2aLog.Log("No value set. Hint map does not contain value, " +
             *              (filledAutofillField == null));
             *  continue;
             * }
             *
             * Kp2aLog.Log("autofill type=" + autofillFieldMetadata.AutofillType);
             * }
             * }
             * }*/

            return(setValueAtLeastOnce);
        }