android.view.autofill.AutofillId Java Examples

The following examples show how to use android.view.autofill.AutofillId. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DebugService.java    From android-AutofillFramework with Apache License 2.0 6 votes vote down vote up
static Dataset newUnlockedDataset(@NonNull Map<String, AutofillId> fields,
        @NonNull String packageName, int i) {
    Dataset.Builder dataset = new Dataset.Builder();
    for (Entry<String, AutofillId> field : fields.entrySet()) {
        String hint = field.getKey();
        AutofillId id = field.getValue();
        String value = i + "-" + hint;

        // We're simple - our dataset values are hardcoded as "N-hint" (for example,
        // "1-username", "2-username") and they're displayed as such, except if they're a
        // password
        String displayValue = hint.contains("password") ? "password for #" + i : value;
        RemoteViews presentation = newDatasetPresentation(packageName, displayValue);
        dataset.setValue(id, AutofillValue.forText(value), presentation);
    }

    return dataset.build();
}
 
Example #2
Source File: SimpleAuthActivity.java    From input-samples with Apache License 2.0 6 votes vote down vote up
private void onYes() {
    Intent myIntent = getIntent();
    Intent replyIntent = new Intent();
    Dataset dataset = myIntent.getParcelableExtra(EXTRA_DATASET);
    if (dataset != null) {
        replyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, dataset);
    } else {
        String[] hints = myIntent.getStringArrayExtra(EXTRA_HINTS);
        Parcelable[] ids = myIntent.getParcelableArrayExtra(EXTRA_IDS);
        boolean authenticateDatasets = myIntent.getBooleanExtra(EXTRA_AUTH_DATASETS, false);
        int size = hints.length;
        ArrayMap<String, AutofillId> fields = new ArrayMap<>(size);
        for (int i = 0; i < size; i++) {
            fields.put(hints[i], (AutofillId) ids[i]);
        }
        FillResponse response =
                DebugService.createResponse(this, fields, 1, authenticateDatasets);
        replyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, response);

    }
    setResult(RESULT_OK, replyIntent);
    finish();
}
 
Example #3
Source File: DebugService.java    From input-samples with Apache License 2.0 6 votes vote down vote up
static Dataset newUnlockedDataset(@NonNull Map<String, AutofillId> fields,
        @NonNull String packageName, int i) {
    Dataset.Builder dataset = new Dataset.Builder();
    for (Entry<String, AutofillId> field : fields.entrySet()) {
        String hint = field.getKey();
        AutofillId id = field.getValue();
        String value = i + "-" + hint;

        // We're simple - our dataset values are hardcoded as "N-hint" (for example,
        // "1-username", "2-username") and they're displayed as such, except if they're a
        // password
        String displayValue = hint.contains("password") ? "password for #" + i : value;
        RemoteViews presentation = newDatasetPresentation(packageName, displayValue);
        dataset.setValue(id, AutofillValue.forText(value), presentation);
    }

    return dataset.build();
}
 
Example #4
Source File: CharSequenceTransformation.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
@Override
public void writeToParcel(Parcel parcel, int flags) {
    final int size = mFields.size();
    final AutofillId[] ids = new AutofillId[size];
    final Pattern[] regexs = new Pattern[size];
    final String[] substs = new String[size];
    Pair<Pattern, String> pair;
    int i = 0;
    for (Entry<AutofillId, Pair<Pattern, String>> entry : mFields.entrySet()) {
        ids[i] = entry.getKey();
        pair = entry.getValue();
        regexs[i] = pair.first;
        substs[i] = pair.second;
        i++;
    }

    parcel.writeParcelableArray(ids, flags);
    parcel.writeSerializable(regexs);
    parcel.writeStringArray(substs);
}
 
Example #5
Source File: DebugService.java    From input-samples with Apache License 2.0 6 votes vote down vote up
/**
 * Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
 */
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
        @NonNull ViewNode node) {
    String hint = getHint(node);
    if (hint != null) {
        AutofillId id = node.getAutofillId();
        if (!fields.containsKey(hint)) {
            Log.v(TAG, "Setting hint '" + hint + "' on " + id);
            fields.put(hint, id);
        } else {
            Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
                    + " because it was already set");
        }
    }
    int childrenSize = node.getChildCount();
    for (int i = 0; i < childrenSize; i++) {
        addAutofillableFields(fields, node.getChildAt(i));
    }
}
 
Example #6
Source File: DebugService.java    From android-AutofillFramework with Apache License 2.0 6 votes vote down vote up
/**
 * Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
 */
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
        @NonNull ViewNode node) {
    String hint = getHint(node);
    if (hint != null) {
        AutofillId id = node.getAutofillId();
        if (!fields.containsKey(hint)) {
            Log.v(TAG, "Setting hint '" + hint + "' on " + id);
            fields.put(hint, id);
        } else {
            Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
                    + " because it was already set");
        }
    }
    int childrenSize = node.getChildCount();
    for (int i = 0; i < childrenSize; i++) {
        addAutofillableFields(fields, node.getChildAt(i));
    }
}
 
Example #7
Source File: BasicService.java    From android-AutofillFramework with Apache License 2.0 6 votes vote down vote up
/**
 * Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
 */
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
        @NonNull ViewNode node) {
    String[] hints = node.getAutofillHints();
    if (hints != null) {
        // We're simple, we only care about the first hint
        String hint = hints[0].toLowerCase();

        if (hint != null) {
            AutofillId id = node.getAutofillId();
            if (!fields.containsKey(hint)) {
                Log.v(TAG, "Setting hint '" + hint + "' on " + id);
                fields.put(hint, id);
            } else {
                Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
                        + " because it was already set");
            }
        }
    }
    int childrenSize = node.getChildCount();
    for (int i = 0; i < childrenSize; i++) {
        addAutofillableFields(fields, node.getChildAt(i));
    }
}
 
Example #8
Source File: BasicService.java    From input-samples with Apache License 2.0 6 votes vote down vote up
/**
 * Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
 */
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
        @NonNull ViewNode node) {
    String[] hints = node.getAutofillHints();
    if (hints != null) {
        // We're simple, we only care about the first hint
        String hint = hints[0].toLowerCase();

        if (hint != null) {
            AutofillId id = node.getAutofillId();
            if (!fields.containsKey(hint)) {
                Log.v(TAG, "Setting hint '" + hint + "' on " + id);
                fields.put(hint, id);
            } else {
                Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
                        + " because it was already set");
            }
        }
    }
    int childrenSize = node.getChildCount();
    for (int i = 0; i < childrenSize; i++) {
        addAutofillableFields(fields, node.getChildAt(i));
    }
}
 
Example #9
Source File: CharSequenceTransformation.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
@Override
public CharSequenceTransformation createFromParcel(Parcel parcel) {
    final AutofillId[] ids = parcel.readParcelableArray(null, AutofillId.class);
    final Pattern[] regexs = (Pattern[]) parcel.readSerializable();
    final String[] substs = parcel.createStringArray();

    // Always go through the builder to ensure the data ingested by
    // the system obeys the contract of the builder to avoid attacks
    // using specially crafted parcels.
    final CharSequenceTransformation.Builder builder =
            new CharSequenceTransformation.Builder(ids[0], regexs[0], substs[0]);

    final int size = ids.length;
    for (int i = 1; i < size; i++) {
        builder.addField(ids[i], regexs[i], substs[i]);
    }
    return builder.build();
}
 
Example #10
Source File: Dataset.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
private void setLifeTheUniverseAndEverything(@NonNull AutofillId id,
        @Nullable AutofillValue value, @Nullable RemoteViews presentation,
        @Nullable DatasetFieldFilter filter) {
    Preconditions.checkNotNull(id, "id cannot be null");
    if (mFieldIds != null) {
        final int existingIdx = mFieldIds.indexOf(id);
        if (existingIdx >= 0) {
            mFieldValues.set(existingIdx, value);
            mFieldPresentations.set(existingIdx, presentation);
            mFieldFilters.set(existingIdx, filter);
            return;
        }
    } else {
        mFieldIds = new ArrayList<>();
        mFieldValues = new ArrayList<>();
        mFieldPresentations = new ArrayList<>();
        mFieldFilters = new ArrayList<>();
    }
    mFieldIds.add(id);
    mFieldValues.add(value);
    mFieldPresentations.add(presentation);
    mFieldFilters.add(filter);
}
 
Example #11
Source File: SaveInfo.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
private SaveInfo(Builder builder) {
    mType = builder.mType;
    mNegativeButtonStyle = builder.mNegativeButtonStyle;
    mNegativeActionListener = builder.mNegativeActionListener;
    mRequiredIds = builder.mRequiredIds;
    mOptionalIds = builder.mOptionalIds;
    mDescription = builder.mDescription;
    mFlags = builder.mFlags;
    mCustomDescription = builder.mCustomDescription;
    mValidator = builder.mValidator;
    if (builder.mSanitizers == null) {
        mSanitizerKeys = null;
        mSanitizerValues = null;
    } else {
        final int size = builder.mSanitizers.size();
        mSanitizerKeys = new InternalSanitizer[size];
        mSanitizerValues = new AutofillId[size][];
        for (int i = 0; i < size; i++) {
            mSanitizerKeys[i] = builder.mSanitizers.keyAt(i);
            mSanitizerValues[i] = builder.mSanitizers.valueAt(i);
        }
    }
    mTriggerId = builder.mTriggerId;
}
 
Example #12
Source File: ClientViewMetadataBuilder.java    From input-samples with Apache License 2.0 6 votes vote down vote up
private void parseNode(AssistStructure.ViewNode root, List<String> allHints,
        MutableInt autofillSaveType, List<AutofillId> autofillIds,
        List<AutofillId> focusedAutofillIds) {
    String[] hints = root.getAutofillHints();
    if (hints != null) {
        for (String hint : hints) {
            FieldTypeWithHeuristics fieldTypeWithHints = mFieldTypesByAutofillHint.get(hint);
            if (fieldTypeWithHints != null && fieldTypeWithHints.fieldType != null) {
                allHints.add(hint);
                autofillSaveType.value |= fieldTypeWithHints.fieldType.getSaveInfo();
                autofillIds.add(root.getAutofillId());
            }
        }
    }
    if (root.isFocused()) {
        focusedAutofillIds.add(root.getAutofillId());
    }
}
 
Example #13
Source File: LuhnChecksumValidator.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
/** @hide */
@Override
@TestApi
public boolean isValid(@NonNull ValueFinder finder) {
    if (mIds == null || mIds.length == 0) return false;

    final StringBuilder builder = new StringBuilder();
    for (AutofillId id : mIds) {
        final String partialNumber = finder.findByAutofillId(id);
        if (partialNumber == null) {
            if (sDebug) Log.d(TAG, "No partial number for id " + id);
            return false;
        }
        builder.append(partialNumber);
    }

    final String number = builder.toString();
    boolean valid = isLuhnChecksumValid(number);
    if (sDebug) Log.d(TAG, "isValid(" + number.length() + " chars): " + valid);
    return valid;
}
 
Example #14
Source File: ClientViewMetadataBuilder.java    From android-AutofillFramework with Apache License 2.0 6 votes vote down vote up
private void parseNode(AssistStructure.ViewNode root, List<String> allHints,
        MutableInt autofillSaveType, List<AutofillId> autofillIds,
        List<AutofillId> focusedAutofillIds) {
    String[] hints = root.getAutofillHints();
    if (hints != null) {
        for (String hint : hints) {
            FieldTypeWithHeuristics fieldTypeWithHints = mFieldTypesByAutofillHint.get(hint);
            if (fieldTypeWithHints != null && fieldTypeWithHints.fieldType != null) {
                allHints.add(hint);
                autofillSaveType.value |= fieldTypeWithHints.fieldType.getSaveInfo();
                autofillIds.add(root.getAutofillId());
            }
        }
    }
    if (root.isFocused()) {
        focusedAutofillIds.add(root.getAutofillId());
    }
}
 
Example #15
Source File: FillEventHistory.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the <a href="AutofillService.html#FieldClassification">field classification</a>
 * results.
 *
 * <p><b>Note: </b>Only set on events of type {@link #TYPE_CONTEXT_COMMITTED}, when the
 * service requested {@link FillResponse.Builder#setFieldClassificationIds(AutofillId...)
 * field classification}.
 */
@NonNull public Map<AutofillId, FieldClassification> getFieldsClassification() {
    if (mDetectedFieldIds == null) {
        return Collections.emptyMap();
    }
    final int size = mDetectedFieldIds.length;
    final ArrayMap<AutofillId, FieldClassification> map = new ArrayMap<>(size);
    for (int i = 0; i < size; i++) {
        final AutofillId id = mDetectedFieldIds[i];
        final FieldClassification fc = mDetectedFieldClassifications[i];
        if (sVerbose) {
            Log.v(TAG, "getFieldsClassification[" + i + "]: id=" + id + ", fc=" + fc);
        }
        map.put(id, fc);
    }
    return map;
}
 
Example #16
Source File: MultiStepsService.java    From android-AutofillFramework with Apache License 2.0 6 votes vote down vote up
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
        @NonNull ViewNode node) {
    String[] hints = node.getAutofillHints();
    if (hints != null) {
        // We're simple, we only care about the first hint
        String hint = hints[0];
        AutofillId id = node.getAutofillId();
        if (!fields.containsKey(hint)) {
            Log.v(TAG, "Setting hint '" + hint + "' on " + id);
            fields.put(hint, id);
        } else {
            Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
                    + " because it was already set");
        }
    }
    int childrenSize = node.getChildCount();
    for (int i = 0; i < childrenSize; i++) {
        addAutofillableFields(fields, node.getChildAt(i));
    }
}
 
Example #17
Source File: ImageTransformation.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
@Override
public ImageTransformation createFromParcel(Parcel parcel) {
    final AutofillId id = parcel.readParcelable(null);

    final Pattern[] regexs = (Pattern[]) parcel.readSerializable();
    final int[] resIds = parcel.createIntArray();
    final CharSequence[] contentDescriptions = parcel.readCharSequenceArray();

    // Always go through the builder to ensure the data ingested by the system obeys the
    // contract of the builder to avoid attacks using specially crafted parcels.
    final CharSequence contentDescription = contentDescriptions[0];
    final ImageTransformation.Builder builder = (contentDescription != null)
            ? new ImageTransformation.Builder(id, regexs[0], resIds[0], contentDescription)
            : new ImageTransformation.Builder(id, regexs[0], resIds[0]);

    final int size = regexs.length;
    for (int i = 1; i < size; i++) {
        if (contentDescriptions[i] != null) {
            builder.addOption(regexs[i], resIds[i], contentDescriptions[i]);
        } else {
            builder.addOption(regexs[i], resIds[i]);
        }
    }

    return builder.build();
}
 
Example #18
Source File: MultiStepsService.java    From input-samples with Apache License 2.0 5 votes vote down vote up
@NonNull
private ArrayMap<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
    ArrayMap<String, AutofillId> fields = new ArrayMap<>();
    int nodes = structure.getWindowNodeCount();
    for (int i = 0; i < nodes; i++) {
        ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
        addAutofillableFields(fields, node);
    }
    return fields;
}
 
Example #19
Source File: ClientViewMetadataBuilder.java    From android-AutofillFramework with Apache License 2.0 5 votes vote down vote up
public ClientViewMetadata buildClientViewMetadata() {
    List<String> allHints = new ArrayList<>();
    MutableInt saveType = new MutableInt(0);
    List<AutofillId> autofillIds = new ArrayList<>();
    StringBuilder webDomainBuilder = new StringBuilder();
    List<AutofillId> focusedAutofillIds = new ArrayList<>();
    mClientParser.parse((node) -> parseNode(node, allHints, saveType, autofillIds, focusedAutofillIds));
    mClientParser.parse((node) -> parseWebDomain(node, webDomainBuilder));
    String webDomain = webDomainBuilder.toString();
    AutofillId[] autofillIdsArray = autofillIds.toArray(new AutofillId[autofillIds.size()]);
    AutofillId[] focusedIds = focusedAutofillIds.toArray(new AutofillId[focusedAutofillIds.size()]);
    return new ClientViewMetadata(allHints, saveType.value, autofillIdsArray, focusedIds, webDomain);
}
 
Example #20
Source File: BasicService.java    From input-samples with Apache License 2.0 5 votes vote down vote up
/**
 * Parses the {@link AssistStructure} representing the activity being autofilled, and returns a
 * map of autofillable fields (represented by their autofill ids) mapped by the hint associate
 * with them.
 *
 * <p>An autofillable field is a {@link ViewNode} whose {@link #getHint(ViewNode)} metho
 */
@NonNull
private Map<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
    Map<String, AutofillId> fields = new ArrayMap<>();
    int nodes = structure.getWindowNodeCount();
    for (int i = 0; i < nodes; i++) {
        ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
        addAutofillableFields(fields, node);
    }
    return fields;
}
 
Example #21
Source File: DebugService.java    From android-AutofillFramework with Apache License 2.0 5 votes vote down vote up
static FillResponse createResponse(@NonNull Context context,
        @NonNull ArrayMap<String, AutofillId> fields, int numDatasets,
        boolean authenticateDatasets) {
    String packageName = context.getPackageName();
    FillResponse.Builder response = new FillResponse.Builder();
    // 1.Add the dynamic datasets
    for (int i = 1; i <= numDatasets; i++) {
        Dataset unlockedDataset = newUnlockedDataset(fields, packageName, i);
        if (authenticateDatasets) {
            Dataset.Builder lockedDataset = new Dataset.Builder();
            for (Entry<String, AutofillId> field : fields.entrySet()) {
                String hint = field.getKey();
                AutofillId id = field.getValue();
                String value = i + "-" + hint;
                IntentSender authentication =
                        SimpleAuthActivity.newIntentSenderForDataset(context, unlockedDataset);
                RemoteViews presentation = newDatasetPresentation(packageName,
                        "Tap to auth " + value);
                lockedDataset.setValue(id, null, presentation)
                        .setAuthentication(authentication);
            }
            response.addDataset(lockedDataset.build());
        } else {
            response.addDataset(unlockedDataset);
        }
    }

    // 2.Add save info
    Collection<AutofillId> ids = fields.values();
    AutofillId[] requiredIds = new AutofillId[ids.size()];
    ids.toArray(requiredIds);
    response.setSaveInfo(
            // We're simple, so we're generic
            new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_GENERIC, requiredIds).build());

    // 3.Profit!
    return response.build();
}
 
Example #22
Source File: DebugService.java    From input-samples with Apache License 2.0 5 votes vote down vote up
static FillResponse createResponse(@NonNull Context context,
        @NonNull ArrayMap<String, AutofillId> fields, int numDatasets,
        boolean authenticateDatasets) {
    String packageName = context.getPackageName();
    FillResponse.Builder response = new FillResponse.Builder();
    // 1.Add the dynamic datasets
    for (int i = 1; i <= numDatasets; i++) {
        Dataset unlockedDataset = newUnlockedDataset(fields, packageName, i);
        if (authenticateDatasets) {
            Dataset.Builder lockedDataset = new Dataset.Builder();
            for (Entry<String, AutofillId> field : fields.entrySet()) {
                String hint = field.getKey();
                AutofillId id = field.getValue();
                String value = i + "-" + hint;
                IntentSender authentication =
                        SimpleAuthActivity.newIntentSenderForDataset(context, unlockedDataset);
                RemoteViews presentation = newDatasetPresentation(packageName,
                        "Tap to auth " + value);
                lockedDataset.setValue(id, null, presentation)
                        .setAuthentication(authentication);
            }
            response.addDataset(lockedDataset.build());
        } else {
            response.addDataset(unlockedDataset);
        }
    }

    // 2.Add save info
    Collection<AutofillId> ids = fields.values();
    AutofillId[] requiredIds = new AutofillId[ids.size()];
    ids.toArray(requiredIds);
    response.setSaveInfo(
            // We're simple, so we're generic
            new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_GENERIC, requiredIds).build());

    // 3.Profit!
    return response.build();
}
 
Example #23
Source File: ClientViewMetadataBuilder.java    From input-samples with Apache License 2.0 5 votes vote down vote up
public ClientViewMetadata buildClientViewMetadata() {
    List<String> allHints = new ArrayList<>();
    MutableInt saveType = new MutableInt(0);
    List<AutofillId> autofillIds = new ArrayList<>();
    StringBuilder webDomainBuilder = new StringBuilder();
    List<AutofillId> focusedAutofillIds = new ArrayList<>();
    mClientParser.parse((node) -> parseNode(node, allHints, saveType, autofillIds, focusedAutofillIds));
    mClientParser.parse((node) -> parseWebDomain(node, webDomainBuilder));
    String webDomain = webDomainBuilder.toString();
    AutofillId[] autofillIdsArray = autofillIds.toArray(new AutofillId[autofillIds.size()]);
    AutofillId[] focusedIds = focusedAutofillIds.toArray(new AutofillId[focusedAutofillIds.size()]);
    return new ClientViewMetadata(allHints, saveType.value, autofillIdsArray, focusedIds, webDomain);
}
 
Example #24
Source File: SimpleAuthActivity.java    From android-AutofillFramework with Apache License 2.0 5 votes vote down vote up
private static IntentSender newIntentSender(@NonNull Context context,
        @Nullable Dataset dataset, @Nullable String[] hints, @Nullable AutofillId[] ids,
        boolean authenticateDatasets) {
    Intent intent = new Intent(context, SimpleAuthActivity.class);
    if (dataset != null) {
        intent.putExtra(EXTRA_DATASET, dataset);
    } else {
        intent.putExtra(EXTRA_HINTS, hints);
        intent.putExtra(EXTRA_IDS, ids);
        intent.putExtra(EXTRA_AUTH_DATASETS, authenticateDatasets);
    }

    return PendingIntent.getActivity(context, ++sPendingIntentId, intent,
            PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
}
 
Example #25
Source File: SimpleAuthActivity.java    From input-samples with Apache License 2.0 5 votes vote down vote up
private static IntentSender newIntentSender(@NonNull Context context,
        @Nullable Dataset dataset, @Nullable String[] hints, @Nullable AutofillId[] ids,
        boolean authenticateDatasets) {
    Intent intent = new Intent(context, SimpleAuthActivity.class);
    if (dataset != null) {
        intent.putExtra(EXTRA_DATASET, dataset);
    } else {
        intent.putExtra(EXTRA_HINTS, hints);
        intent.putExtra(EXTRA_IDS, ids);
        intent.putExtra(EXTRA_AUTH_DATASETS, authenticateDatasets);
    }

    return PendingIntent.getActivity(context, ++sPendingIntentId, intent,
            PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
}
 
Example #26
Source File: MultiStepsService.java    From android-AutofillFramework with Apache License 2.0 5 votes vote down vote up
@NonNull
private ArrayMap<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
    ArrayMap<String, AutofillId> fields = new ArrayMap<>();
    int nodes = structure.getWindowNodeCount();
    for (int i = 0; i < nodes; i++) {
        ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
        addAutofillableFields(fields, node);
    }
    return fields;
}
 
Example #27
Source File: CharSequenceTransformation.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/** @hide */
@Override
@TestApi
public void apply(@NonNull ValueFinder finder, @NonNull RemoteViews parentTemplate,
        int childViewId) throws Exception {
    final StringBuilder converted = new StringBuilder();
    final int size = mFields.size();
    if (sDebug) Log.d(TAG, size + " multiple fields on id " + childViewId);
    for (Entry<AutofillId, Pair<Pattern, String>> entry : mFields.entrySet()) {
        final AutofillId id = entry.getKey();
        final Pair<Pattern, String> field = entry.getValue();
        final String value = finder.findByAutofillId(id);
        if (value == null) {
            Log.w(TAG, "No value for id " + id);
            return;
        }
        try {
            final Matcher matcher = field.first.matcher(value);
            if (!matcher.find()) {
                if (sDebug) Log.d(TAG, "match for " + field.first + " failed on id " + id);
                return;
            }
            // replaceAll throws an exception if the subst is invalid
            final String convertedValue = matcher.replaceAll(field.second);
            converted.append(convertedValue);
        } catch (Exception e) {
            // Do not log full exception to avoid PII leaking
            Log.w(TAG, "Cannot apply " + field.first.pattern() + "->" + field.second + " to "
                    + "field with autofill id" + id + ": " + e.getClass());
            throw e;
        }
    }
    parentTemplate.setCharSequence(childViewId, "setText", converted);
}
 
Example #28
Source File: AutofillServiceHelper.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
static AutofillId[] assertValid(@Nullable AutofillId[] ids) {
    Preconditions.checkArgument(ids != null && ids.length > 0, "must have at least one id");
    // Can't use Preconditions.checkArrayElementsNotNull() because it throws NPE instead of IAE
    for (int i = 0; i < ids.length; ++i) {
        if (ids[i] == null) {
            throw new IllegalArgumentException("ids[" + i + "] must not be null");
        }
    }
    return ids;
}
 
Example #29
Source File: FillEventHistory.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new event.
 *
 * @param eventType The type of the event
 * @param datasetId The dataset the event was on, or {@code null} if the event was on the
 *                  whole response.
 * @param clientState The client state associated with the event.
 * @param selectedDatasetIds The ids of datasets selected by the user.
 * @param ignoredDatasetIds The ids of datasets NOT select by the user.
 * @param changedFieldIds The ids of fields changed by the user.
 * @param changedDatasetIds The ids of the datasets that havd values matching the
 * respective entry on {@code changedFieldIds}.
 * @param manuallyFilledFieldIds The ids of fields that were manually entered by the user
 * and belonged to datasets.
 * @param manuallyFilledDatasetIds The ids of datasets that had values matching the
 * respective entry on {@code manuallyFilledFieldIds}.
 * @param detectedFieldClassifications the field classification matches.
 *
 * @throws IllegalArgumentException If the length of {@code changedFieldIds} and
 * {@code changedDatasetIds} doesn't match.
 * @throws IllegalArgumentException If the length of {@code manuallyFilledFieldIds} and
 * {@code manuallyFilledDatasetIds} doesn't match.
 *
 * @hide
 */
public Event(int eventType, @Nullable String datasetId, @Nullable Bundle clientState,
        @Nullable List<String> selectedDatasetIds,
        @Nullable ArraySet<String> ignoredDatasetIds,
        @Nullable ArrayList<AutofillId> changedFieldIds,
        @Nullable ArrayList<String> changedDatasetIds,
        @Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
        @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
        @Nullable AutofillId[] detectedFieldIds,
        @Nullable FieldClassification[] detectedFieldClassifications) {
    mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_CONTEXT_COMMITTED,
            "eventType");
    mDatasetId = datasetId;
    mClientState = clientState;
    mSelectedDatasetIds = selectedDatasetIds;
    mIgnoredDatasetIds = ignoredDatasetIds;
    if (changedFieldIds != null) {
        Preconditions.checkArgument(!ArrayUtils.isEmpty(changedFieldIds)
                && changedDatasetIds != null
                && changedFieldIds.size() == changedDatasetIds.size(),
                "changed ids must have same length and not be empty");
    }
    mChangedFieldIds = changedFieldIds;
    mChangedDatasetIds = changedDatasetIds;
    if (manuallyFilledFieldIds != null) {
        Preconditions.checkArgument(!ArrayUtils.isEmpty(manuallyFilledFieldIds)
                && manuallyFilledDatasetIds != null
                && manuallyFilledFieldIds.size() == manuallyFilledDatasetIds.size(),
                "manually filled ids must have same length and not be empty");
    }
    mManuallyFilledFieldIds = manuallyFilledFieldIds;
    mManuallyFilledDatasetIds = manuallyFilledDatasetIds;

    mDetectedFieldIds = detectedFieldIds;
    mDetectedFieldClassifications = detectedFieldClassifications;
}
 
Example #30
Source File: DebugService.java    From android-AutofillFramework with Apache License 2.0 5 votes vote down vote up
/**
 * Parses the {@link AssistStructure} representing the activity being autofilled, and returns a
 * map of autofillable fields (represented by their autofill ids) mapped by the hint associate
 * with them.
 *
 * <p>An autofillable field is a {@link ViewNode} whose {@link #getHint(ViewNode)} metho
 */
@NonNull
private ArrayMap<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
    ArrayMap<String, AutofillId> fields = new ArrayMap<>();
    int nodes = structure.getWindowNodeCount();
    for (int i = 0; i < nodes; i++) {
        ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
        addAutofillableFields(fields, node);
    }
    return fields;
}